Post new topic Reply to topic  [ 10 posts ] 
Author Message
PostPosted: Fri Nov 22, 2002 3:32 am 
 Post subject: ds1_load() D2Common.6FD76520 1.09b
 
Offline
Moderator
Moderator
Principality
User avatar

Age: 35
Joined: Sat May 25, 2002 2:39 pm
Posts: 2738
Location: La Garenne Colombes (near Paris)
Gender: Male
Thanks go to
  • Myhrginoc, he provide me the asm code (I didn't know anything about Ollydbg 2 weeks ago), and also made the first comments that really helped me to start.
  • SVR, for having done half of the work, always beeing here when I lacked some asm knowledge, and having make some errors (that way I can say "I helped too" ;) )



DESCRIPTION :
This function load a .DS1 (a map of the game). Extracted from D2Common v1.09b. In the v 1.09d it's at 6FD76530 (just + 00000010 than in 1.09b).

This function takes one parameter on the stack, the pointer to the ds1 file name string. It also takes parameters in ECX and EDX. ECX is an offset to the DS1_INFO structure ('this' object in C++).


STRUCTURES USED :

DS1_INFO
========
   + 00  dword  UNK_TYPE      : type of the unknown layer
                                     0 means no unknown layer and no unknown datas between the
                                     Objects and Paths datas.
                                     1 or 2 means there's such datas.
   + 04  dword  DS1_PTR       : DS1 file pointer in heap
   + 08  dword  ?             : unused
   + 0C  dword  WIDTH         : in # of tiles
   + 10  dword  HEIGHT        : in # of tiles
   + 14  dword  WALL_NUM      : # of walls layers
   + 18  dword  FLOOR_NUM     : # of floor layers
   + 1C  dword  OFF_DIR_1     : pointer to direction layer 1
   + 20  dword  OFF_DIR_2     : pointer to direction layer 2
   + 24  dword  OFF_DIR_3     : pointer to direction layer 3
   + 28  dword  OFF_DIR_4     : pointer to direction layer 4
   + 2C  dword  OFF_WALL_1    : pointer to wall layer 1
   + 30  dword  OFF_WALL_2    : pointer to wall layer 2
   + 34  dword  OFF_WALL_3    : pointer to wall layer 3
   + 38  dword  OFF_WALL_4    : pointer to wall layer 4
   + 3C  dword  OFF_FLOOR_1   : pointer to floor layer 1
   + 40  dword  OFF_FLOOR_2   : pointer to floor layer 2
   + 44  dword  OFF_SHAD      : pointer to shadow layer
   + 48  dword  OFF_UNK       : pointer to unknown layer (something to make groups of tiles I think)
   + 4C  dword  UNK_NUM       : # of lines in the unknown datas, something to do with the Unknown layer
   + 50  dword  UNK_PTR       : pointer for storing these unknown lines, table of UNK_NUM elements of UNK_STRUCT
   + 54  dword  START_OBJ_PTR : pointer to 1st element of the linked OBJECT structures



OBJECT
======
(I'm not sure for these 3 first datas)
   + 00  dword  ID      ? : original ID
   + 04  dword  NEW_ID  ? : new ID after possible modifications
   + 08  dword  VERSION ? : version of the ds1

   + 0C  dword  OBJ_X     : X coordinate in # of sub-tiles
   + 10  dword  OBJ_Y     : Y coordinate in # of sub-tiles
   + 14  dword  FLAGS     : flags of this object
   + 18  dword  PATH_PTR  : pointer to a simple PATHS_INFO structure, NULL if no paths for this object
   + 1C  dword  NEXT_PTR  : pointer to next OBJECT in the linked list, NULL if none



PATHS_INFO
==========
   + 00  dword  ACTION_NUM : # of actions for this NPC
   + 04  dword  ACTION_PTR : pointer to a table of ACTION structure



ACTION
=======
   + 00  dword  ACTION_CODE : action to do at these coordinates (default 1)
   + 04  dword  PATH_X      : X coordinate in # of sub-tiles
   + 08  dword  PATH_Y      : Y coordinate in # of sub-tiles


UNK_STRUCT
==========
   + 00  dword  DW_1 : unknown dword 1
   + 04  dword  DW_2 : unknown dword 2
   + 08  dword  DW_3 : unknown dword 3
   + 0C  dword  DW_4 : unknown dword 4
   + 10  dword  DW_5 : unknown dword 5 (only fill if VERSION > 13)
   + 14  dword  ?    : unused




LOCAL VARIABLES (on stack) :
Some are used for almost anything, so these infos won't be very usefull in fact

SS:[ESP+10]  BYTE   CODE [4]              string of 4 characters, or a dword ?
SS:[ESP+14]  dword  VERSION               version of the ds1
SS:[ESP+18]  dword  DIR_READ              # of direction layers read
SS:[ESP+1C]  dword  TMP / TYPE            # of tiles in 1 layer, object's type
SS:[ESP+20]  dword  ACT                   act range from 0 to 4, default = 0
SS:[ESP+24]  dword  OBJ_NUM / NPC_NUM     # of objects / # of NPC paths
SS:[ESP+2C]  dword  CUR_DIR_OFF / NEW_ID  pointer to current direction offset data in INFO / New ID of an object

_________________
DT1 Tools - DS1 Editor - MPQ list file - Extracting D2 Animation tutorial
"Sorry I can't give you offsets or anything, my dlls are always very mutant compared to what's in the release" - Isolde, aka Peter Hu, 30 Jun 2002


Last edited by Paul Siramy on Fri Nov 22, 2002 3:41 am, edited 1 time in total.

Top
 Profile E-mail  
 
PostPosted: Fri Nov 22, 2002 3:33 am 
 Post subject:
 
Offline
Moderator
Moderator
Principality
User avatar

Age: 35
Joined: Sat May 25, 2002 2:39 pm
Posts: 2738
Location: La Garenne Colombes (near Paris)
Gender: Male
READ DS1 HEADER :

6FD76520  /$ 83EC 18              SUB ESP,18                            ;  make 6 dword local variables
6FD76523  |. 53                   PUSH EBX                              ;  save EBX
6FD76524  |. 55                   PUSH EBP                              ;  save EBP
6FD76525  |. 56                   PUSH ESI                              ;  save ESI
6FD76526  |. 57                   PUSH EDI                              ;  save EDI
6FD76527  |. 8BC2                 MOV EAX,EDX                           ;  EAX = parameter 2
6FD76529  |. 8BD9                 MOV EBX,ECX                           ;  EBX = parameter 1
                                                                        ;    This parameter is 'this' (DS1_INFO)

6FD7652B  |. 8B5424 2C            MOV EDX,DWORD PTR SS:[ESP+2C]         ;  EDX = ?
6FD7652F  |. 68 1C040000          PUSH 41C                              ;  PUSH 1052
6FD76534  |. 68 EC46DD6F          PUSH D2Common.6FDD46EC                ;  ASCII "C:\Projects\Diablo2\Source\D2Common\DRLG\Preset.cpp"
6FD76539  |. 6A 00                PUSH 0                                ;  PUSH 0
6FD7653B  |. 8BC8                 MOV ECX,EAX                           ;  ECX = parameter 2
6FD7653D  |. E8 62D30300          CALL D2Common.6FDB38A4                ;  This call loads a DS1 file to heap,
                                                                        ;     EAX returns with heap pointer

6FD76542  |. 8BF0                 MOV ESI,EAX                           ;  Heap pointer points to VERSION
6FD76544  |. 8973 04              MOV DWORD PTR DS:[EBX+4],ESI          ;  save DS1_PTR
6FD76547  |. 8B46 04              MOV EAX,DWORD PTR DS:[ESI+4]          ;  EAX = WIDTH
6FD7654A  |. 8B3E                 MOV EDI,DWORD PTR DS:[ESI]            ;  EDI = VERSION
6FD7654C  |. 83C6 04              ADD ESI,4                             ;  move pointer to WIDTH
6FD7654F  |. 83C6 04              ADD ESI,4                             ;  move pointer to HEIGHT
6FD76552  |. 8943 0C              MOV DWORD PTR DS:[EBX+C],EAX          ;  save WIDTH
6FD76555  |. C74424 20 00000000   MOV DWORD PTR SS:[ESP+20],0           ;  ACT = 0
6FD7655D  |. 897C24 14            MOV DWORD PTR SS:[ESP+14],EDI         ;  save VERSION
6FD76561  |. 8B0E                 MOV ECX,DWORD PTR DS:[ESI]            ;  ECX = HEIGHT
6FD76563  |. 83C6 04              ADD ESI,4                             ;  move pointer to next data
6FD76566  |. 83FF 08              CMP EDI,8                             ;  VERSION = 8 ?
6FD76569  |. 894B 10              MOV DWORD PTR DS:[EBX+10],ECX         ;  save HEIGHT
6FD7656C  |. 7C 16                JL SHORT D2Common.6FD76584            ;  VERSION < 8 ==> goto ACT_DONE

                                                                        ;  else here VERSION >= 8
                                                                        ;     so current data = ACT

6FD7656E  |. 8B06                 MOV EAX,DWORD PTR DS:[ESI]            ;  EAX = ACT
6FD76570  |. 83C6 04              ADD ESI,4                             ;  move pointer to next data
6FD76573  |. 83F8 04              CMP EAX,4                             ;  ACT = 4 ?
6FD76576  |. 894424 20            MOV DWORD PTR SS:[ESP+20],EAX         ;  save ACT
6FD7657A  |. 7E 08                JLE SHORT D2Common.6FD76584           ;  ACT <= 4  ==> goto ACT_DONE

6FD7657C  |. C74424 20 04000000   MOV DWORD PTR SS:[ESP+20],4           ;  else replace the save value of ACT by 4


ACT_DONE :
==========
6FD76584  |> 83FF 0A              CMP EDI,0A                            ;  VERSION = 10 ?
6FD76587  |. C703 00000000        MOV DWORD PTR DS:[EBX],0              ;  UNK_TYPE = 0
6FD7658D  |. 7C 07                JL SHORT D2Common.6FD76596            ;  VERSION < 10 ==> goto UNK_TYPE_DONE

                                                                        ;  else here VERSION >= 10
                                                                        ;     so current data = UNK_TYPE

6FD7658F  |. 8B16                 MOV EDX,DWORD PTR DS:[ESI]            ;  EDX = UNK_TYPE
6FD76591  |. 83C6 04              ADD ESI,4                             ;  move pointer to next data
6FD76594  |. 8913                 MOV DWORD PTR DS:[EBX],EDX            ;  save UNK_TYPE


UNK_TYPE_DONE :
===============
6FD76596  |> 83FF 03              CMP EDI,3                             ;  VERSION = 3 ?
6FD76599  |. 7C 19                JL SHORT D2Common.6FD765B4            ;  VERSION < 3 ==> goto FILE_STRINGS_DONE

                                                                        ;  else here VERSION >= 3
                                                                        ;     so current data = NUM_FILES

6FD7659B  |. 8B06                 MOV EAX,DWORD PTR DS:[ESI]            ;  EAX = NUM_FILES
6FD7659D  |. 83C6 04              ADD ESI,4                             ;  ESI points to the first file string position
                                                                        ;     or to WALL_NUM if no strings.

6FD765A0  |. 85C0                 TEST EAX,EAX                          ;  NUM_FILES positive ?
6FD765A2  |. 7E 10                JLE SHORT D2Common.6FD765B4           ;  NUM_FILES <= 0 ==> goto FILE_STRINGS_DONE
6FD765A4  |. 8BE8                 MOV EBP,EAX                           ;  EBP = NUM_FILES

6FD765A6  |> 8BCE                 /MOV ECX,ESI                          ;  This loop gets the length of each file string
6FD765A8  |. E8 A0D30300          |CALL D2Common.6FDB394D               ;  and moves a pointer to the first position past
6FD765AD  |. 4D                   |DEC EBP                              ;  that string's null terminator
6FD765AE  |. 8D7406 01            |LEA ESI,DWORD PTR DS:[ESI+EAX+1]
6FD765B2  |.^75 F2                \JNZ SHORT D2Common.6FD765A6          ;  Once fully looped, ESI points to WALL_NUM


FILE_STRINGS_DONE :
===================
6FD765B4  |> 8B6B 10              MOV EBP,DWORD PTR DS:[EBX+10]         ; EBP = HEIGHT
6FD765B7  |. 8B43 0C              MOV EAX,DWORD PTR DS:[EBX+C]          ; EAX = WIDTH
6FD765BA  |. 45                   INC EBP                               ; HEIGHT ++
6FD765BB  |. 40                   INC EAX                               ; WIDTH  ++
6FD765BC  |. 0FAFE8               IMUL EBP,EAX                          ; signed multiplication of WIDTH per HEIGHT
                                                                        ;    EBP = # of tiles in 1 layer

6FD765BF  |. 83FF 09              CMP EDI,9                             ;  VERSION = 9 ?
6FD765C2  |. 896C24 1C            MOV DWORD PTR SS:[ESP+1C],EBP         ;  TMP = # of tiles in 1 layer
                                                                        ;     note : not used

6FD765C6  |. 7C 08                JL SHORT D2Common.6FD765D0            ;  VERSION < 9 ==> goto NO_SPECIAL_SKIP

6FD765C8  |. 83FF 0E              CMP EDI,0E                            ;  VERSION = 14 ?
6FD765CB  |. 7D 03                JGE SHORT D2Common.6FD765D0           ;  VERSION >= 14 ==> goto NO_SPECIAL_SKIP

                                                                        ;  else here VERSION is between 9 and 13 inclusive

6FD765CD  |. 83C6 08              ADD ESI,8                             ;  skip 2 dwords


NO_SPECIAL_SKIP :
=================
6FD765D0  |> 83FF 04              CMP EDI,4                             ;  VERSION = 4 ?
6FD765D3  |. 7C 65                JL SHORT D2Common.6FD7663A            ;  VERSION < 4 ==> goto OFFSETS_VERSION_<_4

                                                                        ;  else here VERSION >= 4

6FD765D5  |. 8B0E                 MOV ECX,DWORD PTR DS:[ESI]            ;  ECX = WALL_NUM
6FD765D7  |. 83C6 04              ADD ESI,4                             ;  move pointer to next data
6FD765DA  |. 83FF 10              CMP EDI,10                            ;  VERSION = 16 ?
6FD765DD  |. 894B 14              MOV DWORD PTR DS:[EBX+14],ECX         ;  save WALL_NUM
6FD765E0  |. 7C 0A                JL SHORT D2Common.6FD765EC            ;  VERSION < 16 ==> goto FLOOR_NUM_DEFAULT

                                                                        ;  else here VERSION >= 16

6FD765E2  |. 8B16                 MOV EDX,DWORD PTR DS:[ESI]            ;  EDX = FLOOR_NUM
6FD765E4  |. 83C6 04              ADD ESI,4                             ;  move pointer to next data
6FD765E7  |. 8953 18              MOV DWORD PTR DS:[EBX+18],EDX         ;  save FLOOR_NUM
6FD765EA  |. EB 07                JMP SHORT D2Common.6FD765F3           ;  goto WALL_OFFSETS


FLOOR_NUM_DEFAULT :
==================
6FD765EC  |> C743 18 01000000     MOV DWORD PTR DS:[EBX+18],1           ;  save a default value for FLOOR_NUM : 1


WALL_OFFSETS :
==============

VERSION >= 16.
Note : WALL layers are in fact 2 layers, first one have the usual Prop1, Prop2, Prop3, Prop4 datas of each Tiles, then the immediatly next layer have the Direction of each Tiles. Here we save the offsets of the WALL layers (props and directions), for accessing them easily later.

6FD765F3  |> 8B43 14              MOV EAX,DWORD PTR DS:[EBX+14]         ;  EAX = WALL_NUM
6FD765F6  |. 33D2                 XOR EDX,EDX                           ;  EDX = 0
6FD765F8  |. 85C0                 TEST EAX,EAX                          ;  WALL_NUM positive ?
6FD765FA  |. 7E 1C                JLE SHORT D2Common.6FD76618           ;  WALL_NUM <= 0 ==> goto FLOOR_OFFSETS

                                                                        ;  else here WALL_NUM > 0

6FD765FC  |. 8D0CAD 00000000      LEA ECX,DWORD PTR DS:[EBP*4]          ;  ECX = # of * BYTES * in 1 layer
6FD76603  |. 8D43 1C              LEA EAX,DWORD PTR DS:[EBX+1C]         ;  EAX = address of OFF_DIR_1

                                                                        ;  currently, ESI is pointing to the 1st tile
                                                                        ;  of the 1st WALL layer

6FD76606  |> 8970 10              /MOV DWORD PTR DS:[EAX+10],ESI        ;  save OFF_WALL_x
6FD76609  |. 03F1                 |ADD ESI,ECX                          ;  move pointer to next layer
6FD7660B  |. 8930                 |MOV DWORD PTR DS:[EAX],ESI           ;  save OFF_DIR_x
6FD7660D  |. 03F1                 |ADD ESI,ECX                          ;  move pointer to next layer
6FD7660F  |. 42                   |INC EDX                              ;  EDX ++
6FD76610  |. 83C0 04              |ADD EAX,4                            ;  move EAX to next OFF_DIR_x data
6FD76613  |. 3B53 14              |CMP EDX,DWORD PTR DS:[EBX+14]        ;  # of WALL layers read = WALL_NUM ?
6FD76616  |.^7C EE                \JL SHORT D2Common.6FD76606           ;  # of WALL layers read < WALL_NUM ==> loop


FLOOR_OFFSETS :
===============
Here we save the offsets of the FLOOR layers (Prop1 thru 4)

6FD76618  |> 8B43 18              MOV EAX,DWORD PTR DS:[EBX+18]         ;  EAX = FLOOR_NUM
6FD7661B  |. 33C9                 XOR ECX,ECX                           ;  ECX = 0
6FD7661D  |. 85C0                 TEST EAX,EAX                          ;  FLOOR_NUM positive ?
6FD7661F  |. 7E 3B                JLE SHORT D2Common.6FD7665C           ;  FLOOR_NUM <= 0 ==> goto READ_TILES

                                                                        ;  else here FLOOR_NUM > 0

6FD76621  |. 8D14AD 00000000      LEA EDX,DWORD PTR DS:[EBP*4]          ;  EDX = # of * BYTES * in 1 layer
6FD76628  |. 8D43 3C              LEA EAX,DWORD PTR DS:[EBX+3C]         ;  EAX = address of OFF_FLOOR_1 in INFO

                                                                        ;  currently, ESI is pointing to the 1st tile
                                                                        ;  of the 1st FLOOR layer

6FD7662B  |> 8930                 /MOV DWORD PTR DS:[EAX],ESI           ;  save OFF_FLOOR_x
6FD7662D  |. 03F2                 |ADD ESI,EDX                          ;  move pointer to next layer
6FD7662F  |. 41                   |INC ECX                              ;  ECX ++
6FD76630  |. 83C0 04              |ADD EAX,4                            ;  move EAX to next OFF_FLOOR_x data
6FD76633  |. 3B4B 18              |CMP ECX,DWORD PTR DS:[EBX+18]        ;  # of FLOOR layers read = FLOOR_NUM ?
6FD76636  |.^7C F3                \JL SHORT D2Common.6FD7662B           ;  # of FLOOR layers read < FLOOR_NUM ==> loop

6FD76638  |. EB 22                JMP SHORT D2Common.6FD7665C           ;  goto READ_TILES


OFFSETS_VERSION_<_4 :
=====================

if VERSION < 4, then we'll have hardcoded layers, in that order :
   * WALL 1
   * FLOOR 1 (not direction !)
   * DIRECTION 1
   * UNKNOWN layer
   * SHADOW layer (handle later)

6FD7663A  |> 8D04AD 00000000      LEA EAX,DWORD PTR DS:[EBP*4]          ;  EAX = # of * BYTES * in 1 layer
6FD76641  |. 8973 2C              MOV DWORD PTR DS:[EBX+2C],ESI         ;  current address in OFF_WALL_1
6FD76644  |. 03F0                 ADD ESI,EAX                           ;  move pointer to next layer
6FD76646  |. C743 14 01000000     MOV DWORD PTR DS:[EBX+14],1           ;  WALL_NUM = 1
6FD7664D  |. 8973 3C              MOV DWORD PTR DS:[EBX+3C],ESI         ;  current address in OFF_FLOOR_1
6FD76650  |. 03F0                 ADD ESI,EAX                           ;  move pointer to next layer
6FD76652  |. 8973 1C              MOV DWORD PTR DS:[EBX+1C],ESI         ;  current address in OFF_DIR_1
6FD76655  |. 03F0                 ADD ESI,EAX                           ;  move pointer to next layer
6FD76657  |. 8973 48              MOV DWORD PTR DS:[EBX+48],ESI         ;  current address in OFF_UNK
6FD7665A  |. 03F0                 ADD ESI,EAX                           ;  move pointer to next layer

_________________
DT1 Tools - DS1 Editor - MPQ list file - Extracting D2 Animation tutorial
"Sorry I can't give you offsets or anything, my dlls are always very mutant compared to what's in the release" - Isolde, aka Peter Hu, 30 Jun 2002


Top
 Profile E-mail  
 
PostPosted: Fri Nov 22, 2002 3:34 am 
 Post subject:
 
Offline
Moderator
Moderator
Principality
User avatar

Age: 35
Joined: Sat May 25, 2002 2:39 pm
Posts: 2738
Location: La Garenne Colombes (near Paris)
Gender: Male
CONVERT DIRECTIONS / SHADOW LAYER / UNKNON LAYER :

READ_TILES :
============
6FD7665C  |> 83FF 07              CMP EDI,7                             ;  VERSION = 7 ?
6FD7665F  |. 7D 56                JGE SHORT D2Common.6FD766B7           ;  VERSION >= 7 ==> goto ALL_DIR_CONV_DONE

                                                                        ;  else here VERSION < 7
                                                                        ;  we'll convert direction values !

6FD76661  |. 8B43 14              MOV EAX,DWORD PTR DS:[EBX+14]         ;  EAX = WALL_NUM
6FD76664  |. C74424 18 00000000   MOV DWORD PTR SS:[ESP+18],0           ;  DIR_READ = 0
6FD7666C  |. 85C0                 TEST EAX,EAX                          ;  WALL_NUM positive ?
6FD7666E  |. 7E 47                JLE SHORT D2Common.6FD766B7           ;  WALL_NUM <= 0 ==> goto ALL_DIR_CONV_DONE

                                                                        ;  else here WALL_NUM > 0

6FD76670  |. 8D43 1C              LEA EAX,DWORD PTR DS:[EBX+1C]         ;  EAX = adress of OFF_DIR_1
6FD76673  |. 894424 2C            MOV DWORD PTR SS:[ESP+2C],EAX         ;  CUR_DIR_OFF = adress of OFF_DIR_1


LOOP_CONV_DIR :
===============
6FD76677  |> 8B4C24 2C            /MOV ECX,DWORD PTR SS:[ESP+2C]        ;  ECX = adress of OFF_DIR_x in INFO
6FD7667B  |. 85ED                 |TEST EBP,EBP                         ;  # of Tiles in 1 layer positive ?
6FD7667D  |. 8B39                 |MOV EDI,DWORD PTR DS:[ECX]           ;  move pointer to value in OFF_DIR_X
                                                                        ;      = move pointer to start of 1 direction layer
6FD7667F  |. 7E 17                |JLE SHORT D2Common.6FD76698          ;  # of Tiles in 1 layer <= 0 ==> goto DIR_CONV_DONE

                                                                        ;  else here # of Tiles in 1 layer > 0

6FD76681  |. 8B6C24 1C            |MOV EBP,DWORD PTR SS:[ESP+1C]        ;  EBP = # of Tiles in 1 layer
                                                                        ;      = # of Direction value to process

6FD76685  |> 8B0F                 |/MOV ECX,DWORD PTR DS:[EDI]          ;  ECX = current Direction Tile
6FD76687  |. E8 342B0000          ||CALL D2Common.6FD791C0              ; 


      CODE OF D2Common.6FD791C0 (1.09b) :
      ===================================
      6FD791C0    /$ 8B048D 58FCDB6F   MOV EAX,DWORD PTR DS:[ECX*4+6FDBFC58]  ; EAX = 1 dword from this lookup table
      6FD791C7    \. C3                RETN


      LOOKUP TABLE AT 6FDBFC58 (all dwords, at least 25 elements) :
      =============================================================
      0, 1, 2, 1, 2, 3, 3, 5, 5, 6, 6, 7, 7, 8, 9, A, B, C, D, E, F, 10, 11, 12, 14 <-- lookup values
      (but since I don't know its real size, I'll stop here, as after it start again from 0)

      Note that there's no higher direction in all the ds1 than 19, so this lookup table may have only 19 elements ?



6FD7668C  |. 8907                 ||MOV DWORD PTR DS:[EDI],EAX          ;  current Direction Tile = value from lookup table

6FD7668E  |. 83C7 04              ||ADD EDI,4                           ;  move pointer to next Direction Tile
6FD76691  |. 4D                   ||DEC EBP                             ;  EBP -- (1 less Direction Tile to process)
6FD76692  |.^75 F1                |\JNZ SHORT D2Common.6FD76685         ;  EBP <> 0 ==> loop (read next Direction values)

6FD76694  |. 8B6C24 1C            |MOV EBP,DWORD PTR SS:[ESP+1C]        ;  EBP = # of Tiles in 1 layer


DIR_CONV_DONE :
===============
6FD76698  |> 8B4424 18            |MOV EAX,DWORD PTR SS:[ESP+18]        ; 
6FD7669C  |. 8B5424 2C            |MOV EDX,DWORD PTR SS:[ESP+2C]        ;  EDX = CUR_DIR_OFF
6FD766A0  |. 8B4B 14              |MOV ECX,DWORD PTR DS:[EBX+14]        ;  ECX = WALL_NUM
6FD766A3  |. 40                   |INC EAX                              ;  DIR_READ ++
6FD766A4  |. 83C2 04              |ADD EDX,4                            ;  EDX = next Direction Offset data
6FD766A7  |. 3BC1                 |CMP EAX,ECX                          ;  DIR_READ = WALL_NUM ?
6FD766A9  |. 894424 18            |MOV DWORD PTR SS:[ESP+18],EAX        ; 
6FD766AD  |. 895424 2C            |MOV DWORD PTR SS:[ESP+2C],EDX        ;  CUR_DIR_OFF = next Direction Offset data
6FD766B1  |.^7C C4                \JL SHORT D2Common.6FD76677           ;  DIR_READ < WALL_NUM ==> LOOP_CONV_DIR
                                                                        ;       (will convert next Direction layer)

6FD766B3  |. 8B7C24 14            MOV EDI,DWORD PTR SS:[ESP+14]         ;  EDI = VERSION



ALL_DIR_CONV_DONE :
===================


==========================================================================================================
now we're on the Shadow layer
==========================================================================================================

6FD766B7  |> 8B0B                 MOV ECX,DWORD PTR DS:[EBX]            ;  ECX = UNK_TYPE
6FD766B9  |. 8D04AD 00000000      LEA EAX,DWORD PTR DS:[EBP*4]          ;  EAX = # of * BYTES * in 1 layer
6FD766C0  |. 8973 44              MOV DWORD PTR DS:[EBX+44],ESI         ;  put current address in OFF_SHAD
6FD766C3  |. 03F0                 ADD ESI,EAX                           ;  skip this SHADOW layer



==========================================================================================================
handle of Unknown layer (only present if UNK_TYPE = 1 or 2)
==========================================================================================================

6FD766C5  |. 85C9                 TEST ECX,ECX                          ;  UNK_TYPE = 0 ?
6FD766C7  |. BD 02000000          MOV EBP,2                             ;  EBP = 2
6FD766CC  |. 7E 09                JLE SHORT D2Common.6FD766D7           ;  UNK_TYPE <= 0 ==> goto UNK_LAY_DONE

                                                                        ;  else here UNK_TYPE > 0

6FD766CE  |. 3BCD                 CMP ECX,EBP                           ;  UNK_TYPE = 2 ?
6FD766D0  |. 7F 05                JG SHORT D2Common.6FD766D7            ;  UNK_TYPE > 2 ==> goto UNK_LAY_DONE

                                                                        ;  else here UNK_TYPE is 1 or 2

6FD766D2  |. 8973 48              MOV DWORD PTR DS:[EBX+48],ESI         ;  put current address in OFF_UNK
6FD766D5  |. 03F0                 ADD ESI,EAX                           ;  skip this UNKNOWN layer


UNK_LAY_DONE :
==============

_________________
DT1 Tools - DS1 Editor - MPQ list file - Extracting D2 Animation tutorial
"Sorry I can't give you offsets or anything, my dlls are always very mutant compared to what's in the release" - Isolde, aka Peter Hu, 30 Jun 2002


Last edited by Paul Siramy on Fri Nov 22, 2002 8:10 am, edited 1 time in total.

Top
 Profile E-mail  
 
PostPosted: Fri Nov 22, 2002 3:35 am 
 Post subject:
 
Offline
Moderator
Moderator
Principality
User avatar

Age: 35
Joined: Sat May 25, 2002 2:39 pm
Posts: 2738
Location: La Garenne Colombes (near Paris)
Gender: Male
OBJECTS :

We'll handle objects of Type 1, 2 and 4. In fact, there's no objects of type 4 in all the 2264 ds1 I have checked, so you can skip the complex part of the Type 4 objects.

Apparently, a ds1 can use the Type 2 objects of the previous acts (no check), but it can't use the ones of the further acts (there IS this check). By just removing this check any ds1 should be able to use any objects of Type 2 (like for Type 1 currently).

================================================================================
now we're on the object datas (infos presents only since VERSION 2)
================================================================================

6FD766D7  |> 83FF 01              CMP EDI,1                             ;  VERSION = 1 ?
6FD766DA  |. 0F8E 33020000        JLE D2Common.6FD76913                 ;  VERSION <= 1 ==> goto END_OBJECTS
6FD766E0  |. 8B06                 MOV EAX,DWORD PTR DS:[ESI]            ;  EAX = OBJ_NUM
6FD766E2  |. 83C6 04              ADD ESI,4                             ;  move pointer to next data
6FD766E5  |. 85C0                 TEST EAX,EAX                          ;  OBJ_NUM positive ?

6FD766E7  |. 0F84 26020000        JE D2Common.6FD76913                  ;  OBJ_NUM  = 0 ==> goto END_OBJECTS
                                                                        ;     from SVR : not needed, great compiler ;)

6FD766ED  |. 0F8E 20020000        JLE D2Common.6FD76913                 ;  OBJ_NUM <= 0 ==> goto END_OBJECTS
6FD766F3  |. 894424 24            MOV DWORD PTR SS:[ESP+24],EAX         ;  save OBJ_NUM


READ_OBJECT :
=============
6FD766F7  |> 8B0E                 /MOV ECX,DWORD PTR DS:[ESI]           ;  ECX = TYPE
6FD766F9  |. 8B46 04              |MOV EAX,DWORD PTR DS:[ESI+4]         ;  EAX = ID
6FD766FC  |. 8B5424 20            |MOV EDX,DWORD PTR SS:[ESP+20]        ;  EDX = ACT
6FD76700  |. 83C6 04              |ADD ESI,4                            ;  move pointer to ID
6FD76703  |. 894C24 1C            |MOV DWORD PTR SS:[ESP+1C],ECX        ;  save TYPE
6FD76707  |. 83C6 04              |ADD ESI,4                            ;  move pointer to X
6FD7670A  |. 33FF                 |XOR EDI,EDI                          ;  EDI = 0


switch (type), case 1, 2, 4 default

6FD7670C  |. 49                   |DEC ECX                              ;  TYPE --
6FD7670D  |. 894424 2C            |MOV DWORD PTR SS:[ESP+2C],EAX        ;  NEW_ID = ID
6FD76711  |. 897C24 10            |MOV DWORD PTR SS:[ESP+10],EDI        ;  (dword) CODE = 0
6FD76715  |. 0F84 F3000000        |JE D2Common.6FD7680E                 ;  TYPE = 0 ==> was 1 ==> goto TYPE_IS_1
6FD7671B  |. 49                   |DEC ECX                              ;  TYPE --
6FD7671C  |. 0F84 B3000000        |JE D2Common.6FD767D5                 ;  TYPE = 0 ==> was 2 ==> goto TYPE_IS_2
6FD76722  |. 2BCD                 |SUB ECX,EBP                          ;  TYPE = TYPE - 2

6FD76724  |. 0F85 85010000        |JNZ D2Common.6FD768AF                ;  TYPE <> 0 ==> wasn't 4 ==> goto END_READ_OBJ


TYPE_IS_4 :
===========
6FD7672A  |. 837C24 14 04         |CMP DWORD PTR SS:[ESP+14],4          ;  VERSION = 4 ?
6FD7672F  |. 0F8E 93000000        |JLE D2Common.6FD767C8                ;  VERSION <= 4 ==> goto VERSION_<_5

                                                                        ;  else here VERSION >= 5

6FD76735  |. 8B1485 E446DD6F      |MOV EDX,DWORD PTR DS:[EAX*4+6FDD46E4];  Lookup table for Item code ( with ID )
                                                                        ;     (LookUp is now an offset)

6FD7673C  |. 6A 04                |PUSH 4                               ;  PUSH 4
6FD7673E  |. 8D4424 1C            |LEA EAX,DWORD PTR SS:[ESP+1C]        ;  EAX = address of TYPE
6FD76742  |. 52                   |PUSH EDX                             ;  PUSH Lookup table for Item code ( with ID )
6FD76743  |. 50                   |PUSH EAX                             ;  PUSH address of TYPE
6FD76744  |. E8 27DD0300          |CALL D2Common.6FDB4470               ;  copy_string( & TYPE, LookUp, 4);



===========================================================================================
CODE OF D2Common.6FDB4470 : copy_string(BYTE * PTR_DEST, BYTE * PTR_SRC, DWORD BYTE_NUM)
===========================================================================================
In our case this function copy a string of at most 4 characters from LookUp (wich is an offset) to TYPE.

This function is something like STRNCPY(), but it also fill the end of the DEST string with zero. Apparently, there's some kind of optimization, as it check if PTR_SRC and PTR_END are on a DWORD boundary, for copying AND filling zero. Hence this mess. I don't know if it's optimization or not (I doubt it), but there's something special about copying dwords, see at the COPY_DWORDS label.

6FDB4470    /$ 8B4C24 0C         MOV ECX,DWORD PTR SS:[ESP+C]           ;  ECX = BYTE_NUM
6FDB4474    |. 57                PUSH EDI                               ;  save EDI
6FDB4475    |. 85C9              TEST ECX,ECX                           ;  BYTE_NUM positive ?
6FDB4477    |. 74 7A             JE SHORT D2Common.6FDB44F3             ;  BYTE_NUM = 0 ==> goto END_COPY_BYTES

                                                                        ;  else here BYTE_NUM > 0

6FDB4479    |. 56                PUSH ESI                               ;  save ESI
6FDB447A    |. 53                PUSH EBX                               ;  save EBX
6FDB447B    |. 8BD9              MOV EBX,ECX                            ;  EBX = BYTE_NUM
6FDB447D    |. 8B7424 14         MOV ESI,DWORD PTR SS:[ESP+14]          ;  ESI = PTR_SCR
6FDB4481    |. F7C6 03000000     TEST ESI,3                             ;  PTR_SRC AND 3
6FDB4487    |. 8B7C24 10         MOV EDI,DWORD PTR SS:[ESP+10]          ;  EDI = (dword) CODE
6FDB448B    |. 75 07             JNZ SHORT D2Common.6FDB4494            ;  (PTR_SRC AND 3) <> 0 ==> goto LOOP_SRC_NOT_OK

                                                                        ;  else here PTR_SRC is on a DWORD boundary

6FDB448D    |. C1E9 02           SHR ECX,2                              ;  ECX = DWORD_NUM = BYTE_NUM / 4
                                                                        ;    ( = # of dwords to process)

6FDB4490    |. 75 6F             JNZ SHORT D2Common.6FDB4501            ;  DWORD_NUM <> 0 ==> goto COPY_DWORDS

                                                                        ;  else here DWORD_NUM = 0

6FDB4492    |. EB 21             JMP SHORT D2Common.6FDB44B5            ;  goto COPY_ENDING_BYTES
                                                                        ;    ( to process some eventual BYTE_NUM % 4)


LOOP_SRC_NOT_OK : (ECX = EBX = BYTE_NUM)
=================
6FDB4494    |> 8A06              /MOV AL,BYTE PTR DS:[ESI]              ;  AL = * PTR_SRC
6FDB4496    |. 46                |INC ESI                               ;  PTR_SRC++
6FDB4497    |. 8807              |MOV BYTE PTR DS:[EDI],AL              ;  * PTR_DEST = AL
6FDB4499    |. 47                |INC EDI                               ;  PTR_DEST++
6FDB449A    |. 49                |DEC ECX                               ;  BYTE_NUM--
6FDB449B    |. 74 25             |JE SHORT D2Common.6FDB44C2            ;  BYTE_NUM = 0 ==> goto END_SRC_NOT_OK

                                                                        ;  else here BYTE_NUM <> 0

6FDB449D    |. 84C0              |TEST AL,AL                            ;  AL positive ?
6FDB449F    |. 74 29             |JE SHORT D2Common.6FDB44CA            ;  AL = 0 ==> goto ENDING_FILL_ZERO
6FDB44A1    |. F7C6 03000000     |TEST ESI,3                            ;  PTR_SCR AND 3
6FDB44A7    |.^75 EB             \JNZ SHORT D2Common.6FDB4494           ;  (PTR_SCR AND 3) <> 0 ==> goto LOOP_SRC_NOT_OK

                                                                        ;  else now PTR_SRC is on a DWORD boundary

6FDB44A9    |. 8BD9              MOV EBX,ECX                            ;  EBX = BYTE_NUM
6FDB44AB    |. C1E9 02           SHR ECX,2                              ;  ECX = DWORD_NUM = BYTE_NUM / 4
6FDB44AE    |. 75 51             JNZ SHORT D2Common.6FDB4501            ;  DWORD_NUM <> 0 ==> goto COPY_DWORDS


END_COPY_DWORD : test if BYTE_NUM % 4 bytes to process
================
6FDB44B0    |> 83E3 03           AND EBX,3                              ;  EBX = BYTE_NUM AND 3
6FDB44B3    |. 74 0D             JE SHORT D2Common.6FDB44C2             ;  EBX = 0 ==> goto END_SRC_NOT_OK


COPY_ENDING_BYTES : (ECX = DWORD_NUM)
===================
6FDB44B5    |> 8A06              /MOV AL,BYTE PTR DS:[ESI]              ;  AL = * PTR_SRC
6FDB44B7    |. 46                |INC ESI                               ;  PTR_SRC++
6FDB44B8    |. 8807              |MOV BYTE PTR DS:[EDI],AL              ;  * PTR_DEST = AL
6FDB44BA    |. 47                |INC EDI                               ;  PTR_DEST++
6FDB44BB    |. 84C0              |TEST AL,AL                            ;  AL positive ?
6FDB44BD    |. 74 2F             |JE SHORT D2Common.6FDB44EE            ;  AL = 0 ==> goto END_OF_STRING
6FDB44BF    |. 4B                |DEC EBX                               ;  BYTE_NUM--
6FDB44C0    |.^75 F3             \JNZ SHORT D2Common.6FDB44B5           :  BYTE_NUM <> 0 ==> goto COPY_ENDING_BYTES


END_SRC_NOT_OK :
================
6FDB44C2    |> 8B4424 10         MOV EAX,DWORD PTR SS:[ESP+10]          ;  EAX = PTR_DEST
6FDB44C6    |. 5B                POP EBX                                ;  restore EBX
6FDB44C7    |. 5E                POP ESI                                ;  restore ESI
6FDB44C8    |. 5F                POP EDI                                ;  restore EDI
6FDB44C9    |. C3                RETN                                   ;  RETURN ==> return PTR_DEST;


ENDING_FILL_ZERO : (AL = 0, but BYTE_NUM NOT zero, so fill the end of the PTR_DEST data with zero) (ECX = EBX = BYTE_NUM)
==================
6FDB44CA    |> F7C7 03000000     TEST EDI,3                             ;  PTR_DEST AND 3
6FDB44D0    |. 74 12             JE SHORT D2Common.6FDB44E4             ;  (PTR_DEST AND 3) = 0 ==> goto ENDING_ON_DWORD

                                                                        ;  else here PTR_DEST is NOT on a dword boundary
DEST_NOT_DWORD :
================
6FDB44D2    |> 8807              /MOV BYTE PTR DS:[EDI],AL              ;  * PTR_DEST = AL ( = 0 in fact)
6FDB44D4    |. 47                |INC EDI                               ;  PTR_DEST++
6FDB44D5    |. 49                |DEC ECX                               ;  BYTE_NUM--
6FDB44D6    |. 0F84 8A000000     |JE D2Common.6FDB4566                  ;  BYTE_NUM = 0 ==> goto ENDING
6FDB44DC    |. F7C7 03000000     |TEST EDI,3                            ;  PTR_DEST AND 3
6FDB44E2    |.^75 EE             \JNZ SHORT D2Common.6FDB44D2           ;  (PTR_DEST AND 3) <> 0 ==> goto DEST_NOT_DWORD

                                                                        ;  else here DEST is on a DWORD boundary
ENDING_ON_DWORD :
=================
6FDB44E4    |> 8BD9              MOV EBX,ECX                            ;  EBX = BYTE_NUM
6FDB44E6    |. C1E9 02           SHR ECX,2                              ;  ECX = DWORD_NUM = BYTE_NUM / 4
6FDB44E9    |. 75 6C             JNZ SHORT D2Common.6FDB4557            ;  DWORD_NUM <> 0 ==> goto ENDING_ON_DWORD_2


LOOP_END_OF_STRING :
====================
6FDB44EB    |> 8807              MOV BYTE PTR DS:[EDI],AL               ;  * PTR_DEST = 0
6FDB44ED    |. 47                INC EDI                                ;  PTR_DEST++


END_OF_STRING : (AL = 0)
===============
6FDB44EE    |> 4B                DEC EBX                                ;  BYTE_NUM--
6FDB44EF    |.^75 FA             JNZ SHORT D2Common.6FDB44EB            ;  BYTE_NUM <> 0 ==> goto LOOP_END_OF_STRING
6FDB44F1    |. 5B                POP EBX                                ;  restore EBX
6FDB44F2    |. 5E                POP ESI                                ;  restore ESI


END_COPY_BYTES :
================
6FDB44F3    |> 8B4424 08         MOV EAX,DWORD PTR SS:[ESP+8]           ;  EAX = PTR_DEST
6FDB44F7    |. 5F                POP EDI                                ;  restore EDI
6FDB44F8    |. C3                RETN                                   ;  RETURN ==> return PTR_DEST;


START_COPY_DWORDS :
===================
6FDB44F9    |> 8917              /MOV DWORD PTR DS:[EDI],EDX            ;  on dword : * PTR_DEST = * PTR_SRC
6FDB44FB    |. 83C7 04           |ADD EDI,4                             ;  PTR_DEST on next dword
6FDB44FE    |. 49                |DEC ECX                               ;  DWORD_NUM--
6FDB44FF    |.^74 AF             |JE SHORT D2Common.6FDB44B0            ;  DWORD_NUM = 0 ==> goto END_COPY_DWORD


COPY_DWORDS : (EBX = BYTE_NUM, ECX = DWORD_NUM)
=============

We want to copy a dword from PTR_SRC to PTR_DEST (a string of at most 4 characters from SRC to DEST), then if

  ((* PTR_SRC) XOR (FFFFFFFF) XOR (7EFEFEFF + (* PTR_SRC))) AND 81010100 = 0 ==> we copy it,

(I think this means that if NONE of the bytes of this dword are set to zero, then no termination string at all, so we simply copy the 4 character of the string... but it's just a guess, in fact I don't understand).

else we analyse at most 4 bytes of the PTR_SRC dword to know what to copy :

   if  ((* PTR_SRC & 0x000000FF) == 0)
      * PTR_DEST = 0;
   else if ((* PTR_SRC & 0x0000FF00) == 0)
      * PTR_DEST = * PTR_SRC & 0x000000FF;
   else if ((* PTR_SRC & 0x00FF0000) == 0)
      * PTR_DEST = * PTR_SRC & 0x0000FFFF;
   else if ((* PTR_SRC & 0xFF000000) == 0)
      * PTR_DEST = * PTR_SRC; // it's correct in this case

(in other words, we copy what is before a termination zero of a string, and meanwhile we fill the other bytes to 0)
   

6FDB4501    |> BA FFFEFE7E        MOV EDX,7EFEFEFF                      ;  EDX = 0x7EFEFEFF
                                                                        ;  = 0111-1110  1111-1110  1111-1110  1111-1111
6FDB4506    |. 8B06              |MOV EAX,DWORD PTR DS:[ESI]            ;  EAX = * ((DWORD *) PTR_SRC)
6FDB4508    |. 03D0              |ADD EDX,EAX                           ;  EDX = EDX + * ((DWORD *) PTR_SRC)
6FDB450A    |. 83F0 FF           |XOR EAX,FFFFFFFF                      ; 
6FDB450D    |. 33C2              |XOR EAX,EDX                           ; 
6FDB450F    |. 8B16              |MOV EDX,DWORD PTR DS:[ESI]            ;  EDX = * ((DWORD *) PTR_SRC)
6FDB4511    |. 83C6 04           |ADD ESI,4                             ;  PTR_SRC on next dword
6FDB4514    |. A9 00010181       |TEST EAX,81010100                     ;  EAX = EAX AND 0x81010100
                                                                        ;   AND 1000-0001  0000-0001  0000-0001  0000-0000
6FDB4519    |.^74 DE             |JE SHORT D2Common.6FDB44F9            ;  EAX = 0 ==> goto START_COPY_DWORDS

6FDB451B    |. 84D2              |TEST DL,DL                            ;  * PTR_SRC AND 0x000000FF ?
6FDB451D    |. 74 2C             |JE SHORT D2Common.6FDB454B            ;  zero ==> goto BYTE_0
6FDB451F    |. 84F6              |TEST DH,DH                            ;  * PTR_SRC AND 0x0000FF00 ?
6FDB4521    |. 74 1E             |JE SHORT D2Common.6FDB4541            ;  zero ==> goto BYTE_1
6FDB4523    |. F7C2 0000FF00     |TEST EDX,0FF0000                      ;  * PTR_SRC AND 0x00FF0000 ?
6FDB4529    |. 74 0C             |JE SHORT D2Common.6FDB4537            ;  zero ==> goto BYTE_2
6FDB452B    |. F7C2 000000FF     |TEST EDX,FF000000                     ;  * PTR_SRC AND 0xFF000000 ?
6FDB4531    |.^75 C6             \JNZ SHORT D2Common.6FDB44F9           ;  something ==> goto START_COPY_DWORDS
6FDB4533    |. 8917              MOV DWORD PTR DS:[EDI],EDX             ;  * PTR_DEST = * PTR_SRC
6FDB4535    |. EB 18             JMP SHORT D2Common.6FDB454F            ;  goto AFTER_BYTES_N


BYTE_2 :
========
6FDB4537    |> 81E2 FFFF0000     AND EDX,0FFFF                          ;  EDX = * PTR_SRC & 0x0000FFFF
6FDB453D    |. 8917              MOV DWORD PTR DS:[EDI],EDX             ;  * PTR_DEST = * PTR_SRC & 0x0000FFFF
6FDB453F    |. EB 0E             JMP SHORT D2Common.6FDB454F            ;  goto AFTER_BYTES_N


BYTE_1 :
========
6FDB4541    |> 81E2 FF000000     AND EDX,0FF                            ;  EDX = * PTR_SRC AND 0x000000FF
6FDB4547    |. 8917              MOV DWORD PTR DS:[EDI],EDX             ;  * PTR_DEST = * PTR_SRC AND 0xFF
6FDB4549    |. EB 04             JMP SHORT D2Common.6FDB454F            ;  goto AFTER_BYTES_N

BYTE_0 :
========
6FDB454B    |> 33D2              XOR EDX,EDX                            ;  EDX = 0
6FDB454D    |. 8917              MOV DWORD PTR DS:[EDI],EDX             ;  * PTR_DEST = 0


AFTER_BYTES_N :
===============
6FDB454F    |> 83C7 04           ADD EDI,4                              ;  PTR_DEST on next dword
6FDB4552    |. 33C0              XOR EAX,EAX                            ;  EAX = 0
6FDB4554    |. 49                DEC ECX                                ;  DWORD_NUM--
6FDB4555    |. 74 0A             JE SHORT D2Common.6FDB4561             ;  DWORD_NUM = 0 ==> goto ENDING_ON_DWORD_3


ENDING_ON_DWORD_2 : (EBX = BYTE_NUM, ECX = DWORD_NUM)
===================
we fill explicitly all final dwords to 0

6FDB4557    |> 33C0              XOR EAX,EAX                            ;  EAX = 0

6FDB4559    |> 8907              /MOV DWORD PTR DS:[EDI],EAX            ;  * PTR_DEST = 0
6FDB455B    |. 83C7 04           |ADD EDI,4                             ;  PTR_DEST on next dword
6FDB455E    |. 49                |DEC ECX                               ;  DWORD_NUM--
6FDB455F    |.^75 F8             \JNZ SHORT D2Common.6FDB4559           ;  DWORD_NUM <> 0 ==> loop


ENDING_ON_DWORD_3 : (EBX = BYTE_NUM, ECX = DWORD_NUM) (EAX = 0)
===================
6FDB4561    |> 83E3 03           AND EBX,3                              ;  BYTE_NUM AND 3
6FDB4564    |.^75 85             JNZ SHORT D2Common.6FDB44EB            ;  <> 0 ==> goto LOOP_END_OF_STRING


ENDING :
========

6FDB4566    |> 8B4424 10         MOV EAX,DWORD PTR SS:[ESP+10]          ;  EAX = PTR_DEST
6FDB456A    |. 5B                POP EBX                                ;  restore EBX
6FDB456B    |. 5E                POP ESI                                ;  restore ESI
6FDB456C    |. 5F                POP EDI                                ;  restore EDI
6FDB456D    \. C3                RETN                                   ;  RETURN ==> return PTR_DEST;


=============================================================================================================
continuation of the objects type stuff, still in the case of object with Type 4
=============================================================================================================

6FD76749  |. 83C4 0C              |ADD ESP,0C                           ;  POP stack back


Here, if VERSION < 7, DIR_READ = WALL_NUM, else undefined (0 ?)

6FD7674C  |. C64424 1B 00         |MOV BYTE PTR SS:[ESP+1B],0           ;  DIR_READ &= 0x00FFFFFF

                                                                        ;  EDI is currently = 0 ==> I = 0

we'll process each 3 bytes (the non-zero ones) of DIR_READ

6FD76751  |> 0FBE4C3C 18          |/MOVSX ECX,BYTE PTR SS:[ESP+EDI+18]  ;  ECX = DIR_READ [I];
6FD76756  |. 51                   ||PUSH ECX                            ;  PUSH this byte
6FD76757  |. E8 D0DB0300          ||CALL D2Common.6FDB432C              ;  EAX = to_lower(this byte)
                                                                        ;  (in 1 case something else, too complex for me)

6FD7675C  |. 83C4 04              ||ADD ESP,4                           ;  POP stack back
6FD7675F  |. 88443C 18            ||MOV BYTE PTR SS:[ESP+EDI+18],AL     ;  DIR_READ [I] = AL
6FD76763  |. 47                   ||INC EDI                             ;  I++
6FD76764  |. 83FF 03              ||CMP EDI,3                           ;  I = 3 ?
6FD76767  |.^7C E8                |\JL SHORT D2Common.6FD76751          ;  I < 3 ==> loop

now just replace null code bytes with space

6FD76769  |. 8A4424 18            |MOV AL,BYTE PTR SS:[ESP+18]          ;  AL = DIR_READ [0] = WALL_NUM if VERSION was < 7
6FD7676D  |. C74424 10 00000000   |MOV DWORD PTR SS:[ESP+10],0          ;  (dword) CODE = 0
6FD76775  |. 84C0                 |TEST AL,AL                           ;  AL positive ?
6FD76777  |. 884424 10            |MOV BYTE PTR SS:[ESP+10],AL          ;  CODE [0] = AL
6FD7677B  |. 75 05                |JNZ SHORT D2Common.6FD76782          ;  AL <> 0 ==> goto SKIP_0
6FD7677D  |. C64424 10 20         |MOV BYTE PTR SS:[ESP+10],20          ;  CODE [0] = ' ' (space)


SKIP_0 :
========
6FD76782  |> 8A4424 19            |MOV AL,BYTE PTR SS:[ESP+19]          ;  AL = DIR_READ[1]
6FD76786  |. 84C0                 |TEST AL,AL                           ;  AL positive ?
6FD76788  |. 884424 11            |MOV BYTE PTR SS:[ESP+11],AL          ;  CODE [1] = AL
6FD7678C  |. 75 05                |JNZ SHORT D2Common.6FD76793          ;  AL <> 0 ==> goto SKIP_1
6FD7678E  |. C64424 11 20         |MOV BYTE PTR SS:[ESP+11],20          ;  CODE [1] = ' ' (space)


SKIP_1 :
========
6FD76793  |> 8A4424 1A            |MOV AL,BYTE PTR SS:[ESP+1A]
6FD76797  |. 84C0                 |TEST AL,AL
6FD76799  |. 884424 12            |MOV BYTE PTR SS:[ESP+12],AL          ;  CODE [2] = AL
6FD7679D  |. 75 05                |JNZ SHORT D2Common.6FD767A4
6FD7679F  |. C64424 12 20         |MOV BYTE PTR SS:[ESP+12],20          ;  CODE [2] = ' ' (space)
6FD767A4  |> 8A4424 1B            |MOV AL,BYTE PTR SS:[ESP+1B]
6FD767A8  |. 84C0                 |TEST AL,AL
6FD767AA  |. 884424 13            |MOV BYTE PTR SS:[ESP+13],AL          ;  CODE [3] = AL
6FD767AE  |. 75 05                |JNZ SHORT D2Common.6FD767B5
6FD767B0  |. C64424 13 20         |MOV BYTE PTR SS:[ESP+13],20          ;  CODE [3] = ' ' (space)
6FD767B5  |> 8B4424 10            |MOV EAX,DWORD PTR SS:[ESP+10]
6FD767B9  |. 8D5424 2C            |LEA EDX,DWORD PTR SS:[ESP+2C]        ;  EDX = NEW_ID
6FD767BD  |. 52                   |PUSH EDX
6FD767BE  |. 50                   |PUSH EAX
6FD767BF  |. E8 4C86FDFF          |CALL D2Common.#10601
6FD767C4  |. 8B4424 2C            |MOV EAX,DWORD PTR SS:[ESP+2C]        ;  EAX = NEW_ID


VERSION_<_5 : (in case 4)
=============
6FD767C8  |> C74424 10 03000000   |MOV DWORD PTR SS:[ESP+10],3          ;  (dword) CODE = 3
6FD767D0  |. E9 DA000000          |JMP D2Common.6FD768AF                ;  ==> goto END_READ_OBJ



TYPE_IS_2 :
===========

Now, for both Type 2 and Type 1 objects, we'll make some modifications, eventually. Don't forget that the ACT value range from 0 to 4, so the "ACT = 2 ?" check means in fact "ACT = 3 ?" for us.


6FD767D5  |> 3D 3D020000          |CMP EAX,23D                          ;  ID = 573 ?
6FD767DA  |. 0F84 C8000000        |JE D2Common.6FD768A8                 ;  ID = 573 ==> goto SET_BAD_ID

                                                                        ;  else here ID <> 573

6FD767E0  |. 837C24 14 05         |CMP DWORD PTR SS:[ESP+14],5          ;  VERSION = 5 ?
6FD767E5  |. 0F8E C4000000        |JLE D2Common.6FD768AF                ;  VERSION <= 5 ==> goto END_READ_OBJ
6FD767EB  |. 3D 96000000          |CMP EAX,96                           ;  ID = 150 ?
6FD767F0  |. 0F8D B2000000        |JGE D2Common.6FD768A8                ;  ID >= 150 ==> goto SET_BAD_ID

                                                                        ;  else here ID < 150

6FD767F6  |. 8D0C52               |LEA ECX,DWORD PTR DS:[EDX+EDX*2]     ;  ECX = ACT * 3
6FD767F9  |. 8D0C89               |LEA ECX,DWORD PTR DS:[ECX+ECX*4]     ;  ECX = ACT * 15
6FD767FC  |. 8D0C89               |LEA ECX,DWORD PTR DS:[ECX+ECX*4]     ;  ECX = ACT * 75
6FD767FF  |. 8D1448               |LEA EDX,DWORD PTR DS:[EAX+ECX*2]     ;  EDX = ID + ACT * 150
6FD76802  |. 8B0495 7C36DD6F      |MOV EAX,DWORD PTR DS:[EDX*4+6FDD367C];  ID = Lookup table for Type 2 objects
6FD76809  |. E9 9D000000          |JMP D2Common.6FD768AB                ;  ==> goto CHANGE_ID


TYPE_IS_1 :
===========
6FD7680E  |> 837C24 14 04         |CMP DWORD PTR SS:[ESP+14],4          ;  VERSION = 4 ?
6FD76813  |. 0F8E 80000000        |JLE D2Common.6FD76899                ;  VERSION <= 4 ==> goto TYPE1_VER_<_5

                                                                        ;  else here VERSION > 4

6FD76819  |. 8D0C52               |LEA ECX,DWORD PTR DS:[EDX+EDX*2]     ;  ECX = ACT * 3
6FD7681C  |. 3BD5                 |CMP EDX,EBP                          ;  ACT = 2 ?
6FD7681E  |. 8D0C89               |LEA ECX,DWORD PTR DS:[ECX+ECX*4]     ;  ECX = ACT * 15
6FD76821  |. 8D0488               |LEA EAX,DWORD PTR DS:[EAX+ECX*4]     ;  ID = ID + ACT * 60
6FD76824  |. 8B0485 3442DD6F      |MOV EAX,DWORD PTR DS:[EAX*4+6FDD4234];  ID = Lookup table for Type 1 objects
6FD7682B  |. 894424 2C            |MOV DWORD PTR SS:[ESP+2C],EAX        ;  NEW_ID = ID
6FD7682F  |. 75 2C                |JNZ SHORT D2Common.6FD7685D          ;  ACT <> 2 ==> goto TYPE1_ACT_NOT_2

                                                                        ;  else here ACT = 2 (act 3 for us)

6FD76831  |. 3D 29010000          |CMP EAX,129                          ;  ID = 297 ?
6FD76836  |. 75 0F                |JNZ SHORT D2Common.6FD76847          ;  ID <> 297 ==> goto TYPE1_ACT2_ID_NOT_297

                                                                        ;  else here ID = 297

6FD76838  |. B8 7E010000          |MOV EAX,17E                          ;  ID = 382
6FD7683D  |. 896C24 1C            |MOV DWORD PTR SS:[ESP+1C],EBP        ;  TYPE = 2
6FD76841  |. 894424 2C            |MOV DWORD PTR SS:[ESP+2C],EAX        ;  NEW_ID = 382
6FD76845  |. EB 68                |JMP SHORT D2Common.6FD768AF          ;  ==> goto END_READ_OBJ


TYPE1_ACT2_ID_NOT_297 :
=======================
6FD76847  |> 3D 6E010000          |CMP EAX,16E                          ;  ID = 366 ?
6FD7684C  |. 75 4B                |JNZ SHORT D2Common.6FD76899          ;  ID <> 366 ==> goto TYPE1_VER_<_5
6FD7684E  |. B8 94010000          |MOV EAX,194                          ;  ID = 404
6FD76853  |. 896C24 1C            |MOV DWORD PTR SS:[ESP+1C],EBP        ;  TYPE = 2
6FD76857  |. 894424 2C            |MOV DWORD PTR SS:[ESP+2C],EAX        ;  NEW_ID = 404
6FD7685B  |. EB 52                |JMP SHORT D2Common.6FD768AF          ;  ==> goto END_READ_OBJ


TYPE1_ACT_NOT_2 :
=================
6FD7685D  |> 83FA 04              |CMP EDX,4                            ;  ACT = 4 ? (act 5 for us)
6FD76860  |. 75 37                |JNZ SHORT D2Common.6FD76899          ;  ACT <> 4 ==> goto TYPE1_VER_<_5
6FD76862  |. 3D 19020000          |CMP EAX,219                          ;  ID = 537 ?
6FD76867  |. 7C 1A                |JL SHORT D2Common.6FD76883           ;  ID < 537 ==> goto TYPE1_ACT4_ID_NOT_53X
6FD76869  |. 3D 1B020000          |CMP EAX,21B                          ;  ID = 539 ?
6FD7686E  |. 7F 13                |JG SHORT D2Common.6FD76883           ;  ID > 539 ==> goto TYPE1_ACT4_ID_NOT_53X
6FD76870  |. B9 F5030000          |MOV ECX,3F5                          ;  ECX = 1013
6FD76875  |. 896C24 1C            |MOV DWORD PTR SS:[ESP+1C],EBP        ;  TYPE = 2
6FD76879  |. 2BC8                 |SUB ECX,EAX                          ; 
6FD7687B  |. 8BC1                 |MOV EAX,ECX                          ;  ID = 1013 - ID
6FD7687D  |. 894424 2C            |MOV DWORD PTR SS:[ESP+2C],EAX        ;  NEW_ID = ID
6FD76881  |. EB 2C                |JMP SHORT D2Common.6FD768AF          ;  ==> goto END_READ_OBJ


TYPE1_ACT4_ID_NOT_53X :
=======================
6FD76883  |> 3D 02020000          |CMP EAX,202                          ;  ID = 514 ?
6FD76888  |. 75 0F                |JNZ SHORT D2Common.6FD76899          ;  ID <> 514 ==> goto TYPE1_VER_<_5
6FD7688A  |. B8 CD010000          |MOV EAX,1CD                          ;  ID = 461
6FD7688F  |. 896C24 1C            |MOV DWORD PTR SS:[ESP+1C],EBP        ;  TYPE = 2
6FD76893  |. 894424 2C            |MOV DWORD PTR SS:[ESP+2C],EAX        ;  NEW_ID = 461
6FD76897  |. EB 16                |JMP SHORT D2Common.6FD768AF          ;  ==> goto END_READ_OBJ


TYPE1_VER_<_5 :
===============
6FD76899  |> 3D 3F020000          |CMP EAX,23F                          ;  ID = 575 ?
6FD7689E  |. C74424 10 01000000   |MOV DWORD PTR SS:[ESP+10],1          ;  (dword) CODE = 1
6FD768A6  |. 75 07                |JNZ SHORT D2Common.6FD768AF          ;  ID <> 575 ==> goto END_READ_OBJ


SET_BAD_ID :
============
6FD768A8  |> 83C8 FF              |OR EAX,FFFFFFFF                      ;  ID = -1


CHANGE_ID :
===========
6FD768AB  |> 894424 2C            |MOV DWORD PTR SS:[ESP+2C],EAX        ;  NEW_ID = ID


END_READ_OBJ :
==============
6FD768AF  |> 8B0E                 |MOV ECX,DWORD PTR DS:[ESI]           ;  ECX = X
6FD768B1  |. 8B56 04              |MOV EDX,DWORD PTR DS:[ESI+4]         ;  EDX = Y
6FD768B4  |. 8B6C24 14            |MOV EBP,DWORD PTR SS:[ESP+14]        ;  EBP = VERSION
6FD768B8  |. 83C6 04              |ADD ESI,4                            ;  move pointer to Y
6FD768BB  |. 83C6 04              |ADD ESI,4                            ;  move pointer to next data
6FD768BE  |. 33FF                 |XOR EDI,EDI                          ;  EDI = 0
6FD768C0  |. 83FD 05              |CMP EBP,5                            ;  VERSION = 5 ?
6FD768C3  |. 7E 05                |JLE SHORT D2Common.6FD768CA          ;  VERSION <= 5 ==> goto FLAGS_DONE

                                                                        ;  else here VERSION > 5

6FD768C5  |. 8B3E                 |MOV EDI,DWORD PTR DS:[ESI]           ;  EDI = FLAGS
6FD768C7  |. 83C6 04              |ADD ESI,4                            ;  move pointer to next data


FLAGS_DONE :
============

if TYPE 1 and version < 5, then don't save this object, other case = save it

6FD768CA  |> 837C24 1C 01         |CMP DWORD PTR SS:[ESP+1C],1          ;  TYPE = 1 ?
6FD768CF  |. 75 07                |JNZ SHORT D2Common.6FD768D8          ;  TYPE <> 1 ==> goto SAVE_OBJECT
6FD768D1  |. 837C24 14 04         |CMP DWORD PTR SS:[ESP+14],4          ;  VERSION = 4 ?
6FD768D6  |. 7E 27                |JLE SHORT D2Common.6FD768FF          ;  VERSION <= 4 ==> goto NEXT_OBJECT


SAVE_OBJECT :
=============
6FD768D8  |> 83F8 FF              |CMP EAX,-1                           ;  ID = -1 ?
6FD768DB  |. 74 22                |JE SHORT D2Common.6FD768FF           ;  ID = -1 ==> goto NEXT_OBJECT

6FD768DD  |. 52                   |PUSH EDX                             ;  PUSH Y
6FD768DE  |. 8B5424 14            |MOV EDX,DWORD PTR SS:[ESP+14]        ;  EDX = VERSION
6FD768E2  |. 51                   |PUSH ECX                             ;  PUSH X
6FD768E3  |. 52                   |PUSH EDX                             ;  PUSH VERSION
6FD768E4  |. 50                   |PUSH EAX                             ;  PUSH ID
6FD768E5  |. 8B4424 2C            |MOV EAX,DWORD PTR SS:[ESP+2C]        ;  ID = NEW_ID
6FD768E9  |. 50                   |PUSH EAX                             ;  PUSH ID
6FD768EA  |. 33D2                 |XOR EDX,EDX                          ;  EDX = 0
6FD768EC  |. 33C9                 |XOR ECX,ECX                          ;  ECX = 0

6FD768EE  |. E8 5D26FFFF          |CALL D2Common.6FD68F50               ;  call that function ? :
                                                                        ;  new OBJECT(ID, ID, VERSION, X, Y);


=====================================================================================================

I'm not sure, but it should be ok


6FD68F50    /$ 56                PUSH ESI                               ;  save ESI
6FD68F51    |. 57                PUSH EDI                               ;  save EDI
6FD68F52    |. 8BC2              MOV EAX,EDX                            ;  EAX = 0
6FD68F54    |. 8BF1              MOV ESI,ECX                            ;  ESI = 0
6FD68F56    |. 6A 00             PUSH 0                                 ;  PUSH 0
6FD68F58    |. 68 AC030000       PUSH 3AC                               ;  PUSH 940
6FD68F5D    |. 68 3030DD6F       PUSH D2Common.6FDD3030                 ;  ASCII "C:\Projects\Diablo2\Source\D2Common\DRLG\DrlgRoom.cpp"
6FD68F62    |. BA 20000000       MOV EDX,20                             ;  EDX = 32
6FD68F67    |. 8BC8              MOV ECX,EAX                            ;  ECX = 0
6FD68F69    |. E8 0AAA0400       CALL <JMP.&Fog.#10045>                 ;  allocate 8 dwords
6FD68F6E    |. 8BD0              MOV EDX,EAX                            ;  OBJ_MEM = EAX
6FD68F70    |. B9 08000000       MOV ECX,8                              ;  ECX = 8
6FD68F75    |. 33C0              XOR EAX,EAX                            ;  EAX = 0
6FD68F77    |. 8BFA              MOV EDI,EDX                            ;  EDI = OBJ_MEM
6FD68F79    |. F3:AB             REP STOS DWORD PTR ES:[EDI]            ;  copy 8 dwords
6FD68F7B    |. 8B4424 0C         MOV EAX,DWORD PTR SS:[ESP+C]           ;  EAX = NEW_ID
6FD68F7F    |. 8B4C24 10         MOV ECX,DWORD PTR SS:[ESP+10]          ;  ECX = LookUp
6FD68F83    |. 8902              MOV DWORD PTR DS:[EDX],EAX             ;  OBJ_MEM->ID = NEW_ID
6FD68F85    |. 8B4424 14         MOV EAX,DWORD PTR SS:[ESP+14]          ;  EAX = VERSION
6FD68F89    |. 894A 04           MOV DWORD PTR DS:[EDX+4],ECX           ;  OBJ_MEM->LOOK_UP = LookUp
6FD68F8C    |. 8B4C24 18         MOV ECX,DWORD PTR SS:[ESP+18]          ;  ECX = X
6FD68F90    |. 8942 08           MOV DWORD PTR DS:[EDX+8],EAX           ;  OBJ_MEM->VERSION = VERSION
6FD68F93    |. 8B4424 1C         MOV EAX,DWORD PTR SS:[ESP+1C]          ;  EAX = Y
6FD68F97    |. 85F6              TEST ESI,ESI                           ;  ESI positive ?
6FD68F99    |. 894A 0C           MOV DWORD PTR DS:[EDX+C],ECX           ;  OBJ_MEM->X = X
6FD68F9C    |. 8942 10           MOV DWORD PTR DS:[EDX+10],EAX          ;  OBJ_MEM->Y = Y
6FD68F9F    |. 74 16             JE SHORT D2Common.6FD68FB7             ;  ESI = 0 ==> goto END_ESI_0

6FD68FA1    |. 8B8E CC000000     MOV ECX,DWORD PTR DS:[ESI+CC]          ;  ECX = ?
6FD68FA7    |. 5F                POP EDI                                ;  restore EDI
6FD68FA8    |. 894A 1C           MOV DWORD PTR DS:[EDX+1C],ECX          ;  OBJ_MEM->NEXT_PTR = ?
6FD68FAB    |. 8996 CC000000     MOV DWORD PTR DS:[ESI+CC],EDX          ;  ? = OBJ_MEM
6FD68FB1    |. 8BC2              MOV EAX,EDX                            ;  EAX = OBJ_MEM
6FD68FB3    |. 5E                POP ESI                                ;  restore ESI
6FD68FB4    |. C2 1400           RETN 14                                ;  free 5 dwords and RETURN


END_ESI_0 :
===========
6FD68FB7    |> 5F                POP EDI                                ;  restore EDI
6FD68FB8    |. C742 1C 00000000  MOV DWORD PTR DS:[EDX+1C],0            ;  OBJ_MEM-> = 0
6FD68FBF    |. 8BC2              MOV EAX,EDX                            ;  EAX = OBJ_MEM
6FD68FC1    |. 5E                POP ESI                                ;  restore ESI
6FD68FC2    \. C2 1400           RETN 14                                ;  free 5 dwords and RETURN

=====================================================================================================


add a new object in front of the current linked objects

6FD768F3  |. 8B4B 54              |MOV ECX,DWORD PTR DS:[EBX+54]        ;  get START_OBJ_PTR
6FD768F6  |. 8948 1C              |MOV DWORD PTR DS:[EAX+1C],ECX        ;  CUR_OBJ_PTR->NEXT = START_OBJ_PTR
6FD768F9  |. 8943 54              |MOV DWORD PTR DS:[EBX+54],EAX        ;  START_OBJ_PTR = CUR_OBJ_PTR
6FD768FC  |. 0978 14              |OR DWORD PTR DS:[EAX+14],EDI         ;  CUR_OBJ_PTR->FLAG |= EDI


NEXT_OBJECT :
=============
6FD768FF  |> 8B4424 24            |MOV EAX,DWORD PTR SS:[ESP+24]        ; 
6FD76903  |. BD 02000000          |MOV EBP,2                            ;  EBP = 2
6FD76908  |. 48                   |DEC EAX                              ; 
6FD76909  |. 894424 24            |MOV DWORD PTR SS:[ESP+24],EAX        ;  OBJ_NUM--
6FD7690D  |.^0F85 E4FDFFFF        \JNZ D2Common.6FD766F7                ;  OBJ_NUM <> 0 ==> goto READ_OBJECT

_________________
DT1 Tools - DS1 Editor - MPQ list file - Extracting D2 Animation tutorial
"Sorry I can't give you offsets or anything, my dlls are always very mutant compared to what's in the release" - Isolde, aka Peter Hu, 30 Jun 2002


Last edited by Paul Siramy on Sun Nov 24, 2002 7:56 am, edited 2 times in total.

Top
 Profile E-mail  
 
PostPosted: Fri Nov 22, 2002 3:36 am 
 Post subject:
 
Offline
Moderator
Moderator
Principality
User avatar

Age: 35
Joined: Sat May 25, 2002 2:39 pm
Posts: 2738
Location: La Garenne Colombes (near Paris)
Gender: Male
UNKNOWN DATA / NPC PATHS :


========================================================================================================
UNKNOWN DATAS relative to the UNKNOWN layer (when UNK_TYPE is 1 or 2).

The Unknown layer can be present since version 10, but theses datas can be present only
since version 12, careful.
========================================================================================================

END_OBJECTS :
=============
6FD76913  |> 8B7C24 14            MOV EDI,DWORD PTR SS:[ESP+14]         ;  EDI = VERSION
6FD76917  |. 83FF 0C              CMP EDI,0C                            ;  VERSION = 12 ?
6FD7691A  |. 0F8C 96000000        JL D2Common.6FD769B6                  ;  VERSION < 12 ==> goto NPC_DATAS

                                                                        ;  else here VERSION >= 12

6FD76920  |. 8B03                 MOV EAX,DWORD PTR DS:[EBX]            ;  EAX = UNK_TYPE
6FD76922  |. 85C0                 TEST EAX,EAX                          ;  UNK_TYPE positive ?
6FD76924  |. 0F8E 8C000000        JLE D2Common.6FD769B6                 ;  UNK_TYPE <= 0 ==> goto NPC_DATAS
6FD7692A  |. 3BC5                 CMP EAX,EBP                           ;  UNK_TYPE = 2 ?
6FD7692C  |. 0F8F 84000000        JG D2Common.6FD769B6                  ;  UNK_TYPE > 2 ==> goto NPC_DATAS
6FD76932  |. 83FF 12              CMP EDI,12                            ;  VERSION = 18 ?
6FD76935  |. 7C 03                JL SHORT D2Common.6FD7693A            ;  VERSION < 18 ==> goto NO_SKIP

                                                                        ;  else here VERSION >= 18 and UNK_TYPE is 1 or 2

6FD76937  |. 83C6 04              ADD ESI,4                             ;  move pointer to next data
                                                                        ;  (skip what ? a zero it seems)
NO_SKIP :
=========
                                                                        ;  here VERSION >= 12 and UNK_TYPE is 1 or 2

6FD7693A  |> 8B16                 MOV EDX,DWORD PTR DS:[ESI]            ;  EDX = UNK_NUM
6FD7693C  |. 6A 00                PUSH 0                                ;  PUSH 0
6FD7693E  |. 8BC2                 MOV EAX,EDX                           ;  EAX = UNK_NUM
6FD76940  |. 8953 4C              MOV DWORD PTR DS:[EBX+4C],EDX         ;  save UNK_NUM
6FD76943  |. 68 84050000          PUSH 584                              ;  PUSH 1412
6FD76948  |. 68 EC46DD6F          PUSH D2Common.6FDD46EC                ;  ASCII "C:\Projects\Diablo2\Source\D2Common\DRLG\Preset.cpp"
6FD7694D  |. 8D1440               LEA EDX,DWORD PTR DS:[EAX+EAX*2]      ;  UNK_SIZE = UNK_NUM * 3
6FD76950  |. 33C9                 XOR ECX,ECX                           ;  ECX = 0
6FD76952  |. C1E2 03              SHL EDX,3                             ;  UNK_SIZE == UNK_NUM * 3 * 8
6FD76955  |. 83C6 04              ADD ESI,4                             ;  move pointer to next data
6FD76958  |. E8 1BD00300          CALL <JMP.&Fog.#10045>                ;  allocate UNK_NUM * 6 dwords
                                                                        ;     (table of UNK_NUM elements of UNK_STRUCT)

6FD7695D  |. 8943 50              MOV DWORD PTR DS:[EBX+50],EAX         ;  UNK_PTR = EAX
6FD76960  |. 8B43 4C              MOV EAX,DWORD PTR DS:[EBX+4C]         ;  EAX = UNK_NUM
6FD76963  |. 33C9                 XOR ECX,ECX                           ;  UNK_COUNTER = 0
6FD76965  |. 85C0                 TEST EAX,EAX                          ;  UNK_NUM positive ?
6FD76967  |. 7E 4D                JLE SHORT D2Common.6FD769B6           ;  UNK_NUM <= 0 ==> goto NPC_DATAS
6FD76969  |. 33C0                 XOR EAX,EAX                           ;  IDX = 0


START_UNK_DATA :
================
6FD7696B  |> 8B53 50              /MOV EDX,DWORD PTR DS:[EBX+50]        ;  EDX = UNK_PTR
6FD7696E  |. 8B2E                 |MOV EBP,DWORD PTR DS:[ESI]           ;  EBP = DW_1
6FD76970  |. 83C6 04              |ADD ESI,4                            ;  move pointer to next data
6FD76973  |. 892C10               |MOV DWORD PTR DS:[EAX+EDX],EBP       ;  UNK_STRUCT[IDX]->DW_1 = DW_1

6FD76976  |. 8B53 50              |MOV EDX,DWORD PTR DS:[EBX+50]        ;  EDX = UNK_PTR
6FD76979  |. 8B2E                 |MOV EBP,DWORD PTR DS:[ESI]           ;  EBP = DW_2
6FD7697B  |. 83C6 04              |ADD ESI,4                            ;  move pointer to next data
6FD7697E  |. 896C10 04            |MOV DWORD PTR DS:[EAX+EDX+4],EBP     ;  UNK_STRUCT[IDX]->DW_2 = DW_2

6FD76982  |. 8B53 50              |MOV EDX,DWORD PTR DS:[EBX+50]        ;  EDX = UNK_PTR
6FD76985  |. 8B2E                 |MOV EBP,DWORD PTR DS:[ESI]           ;  EBP = DW_3
6FD76987  |. 83C6 04              |ADD ESI,4                            ;  move pointer to next data
6FD7698A  |. 896C10 08            |MOV DWORD PTR DS:[EAX+EDX+8],EBP     ;  UNK_STRUCT[IDX]->DW_3 = DW_3

6FD7698E  |. 8B53 50              |MOV EDX,DWORD PTR DS:[EBX+50]        ;  EDX = UNK_PTR
6FD76991  |. 8B2E                 |MOV EBP,DWORD PTR DS:[ESI]           ;  EBP = DW_4
6FD76993  |. 83C6 04              |ADD ESI,4                            ;  move pointer to next data
6FD76996  |. 83FF 0D              |CMP EDI,0D                           ;  VERSION = 13 ?
6FD76999  |. 896C10 0C            |MOV DWORD PTR DS:[EAX+EDX+C],EBP     ;  UNK_STRUCT[IDX]->DW_4 = DW_4
6FD7699D  |. 7C 0C                |JL SHORT D2Common.6FD769AB           ;  VERSION < 13 ==> goto NO_DW_5

                                                                        ;  else here VERSION >= 13 and UNK_TYPE is 1 or 2

6FD7699F  |. 8B53 50              |MOV EDX,DWORD PTR DS:[EBX+50]        ;  EDX = UNK_PTR
6FD769A2  |. 8B2E                 |MOV EBP,DWORD PTR DS:[ESI]           ;  EBP = DW_5
6FD769A4  |. 83C6 04              |ADD ESI,4                            ;  move pointer to next data
6FD769A7  |. 896C10 14            |MOV DWORD PTR DS:[EAX+EDX+14],EBP    ;  UNK_STRUCT[IDX]->DW_5 = DW_5


NO_DW_5 :
=========
6FD769AB  |> 8B53 4C              |MOV EDX,DWORD PTR DS:[EBX+4C]        ;  EDX = UNK_NUM
6FD769AE  |. 41                   |INC ECX                              ;  UNK_COUNTER ++
6FD769AF  |. 83C0 18              |ADD EAX,18                           ;  IDX ++ (next UNK_STRUCT)
6FD769B2  |. 3BCA                 |CMP ECX,EDX                          ;  UNK_COUNTER = UNK_NUM ?
6FD769B4  |.^7C B5                \JL SHORT D2Common.6FD7696B           ;  UNK_COUNTER < UNK_NUM ==> goto START_UNK_DATA



============================================================================================================
now we're on the NPC PATHS datas (only present since version 14)

Format of npc paths datas (in the ds1 file) :
   dword = NPC_NUM
   then NPC_NUM datas structured like :
      dword = PATH_NUM
      dword = OBJ_X
      dword = OBJ_Y
      then PATH_NUM datas structured like :
         dword = PATH_X
         dword = PATH_Y
         dword = ACTION (only present since version 15... that means than in version 14 it's always 1)
============================================================================================================


NPC_DATAS :
===========
6FD769B6  |> 83FF 0E              CMP EDI,0E                            ;  VERSION = 14 ?
6FD769B9  |. 7C 53                JL SHORT D2Common.6FD76A0E            ;  VERSION < 14 ==> goto END_OF_LOAD
6FD769BB  |. 8B06                 MOV EAX,DWORD PTR DS:[ESI]            ;  EAX = NPC_NUM
6FD769BD  |. 83C6 04              ADD ESI,4                             ;  move pointer to next data
6FD769C0  |. 85C0                 TEST EAX,EAX                          ;  NPC_NUM positive ?
6FD769C2  |. 7E 4A                JLE SHORT D2Common.6FD76A0E           ;  NPC_NUM <= 0 ==> END_OF_LOAD
6FD769C4  |. 894424 24            MOV DWORD PTR SS:[ESP+24],EAX         ;  save NPC_NUM


START_NEW_NPC :
===============
6FD769C8  |> 8B2E                 MOV EBP,DWORD PTR DS:[ESI]            ;  EBP = PATH_NUM
6FD769CA  |. 8B46 04              MOV EAX,DWORD PTR DS:[ESI+4]          ;  EAX = OBJ_X
6FD769CD  |. 83C6 04              ADD ESI,4                             ;  move pointer to next data
6FD769D0  |. 83C6 04              ADD ESI,4                             ;  move pointer to next_data
6FD769D3  |. 8B0E                 MOV ECX,DWORD PTR DS:[ESI]            ;  ECX = OBJ_Y
6FD769D5  |. 83C6 04              ADD ESI,4                             ;  move pointer to next data
6FD769D8  |. 85ED                 TEST EBP,EBP                          ;  PATH_NUM positive ?
6FD769DA  |. 74 27                JE SHORT D2Common.6FD76A03            ;  PATH_NUM = 0 ==> goto NEXT_NPC

                                                                        ;  else here we'll read PATH_NUM datas

6FD769DC  |. 8B7B 54              MOV EDI,DWORD PTR DS:[EBX+54]         ;  CUR_OBJ_PTR = START_OBJ_PTR
6FD769DF  |. 85FF                 TEST EDI,EDI                          ;  CUR_OBJ_PTR = NULL ?
6FD769E1  |. 74 11                JE SHORT D2Common.6FD769F4            ;  CUR_OBJ_PTR = NULL ==> goto OBJ_NOT_FOUND


TRY_THIS_OBJ :
==============
6FD769E3  |> 3947 0C              /CMP DWORD PTR DS:[EDI+C],EAX         ;  CUR_OBJ_PTR->X = OBJ_X ?
6FD769E6  |. 75 05                |JNZ SHORT D2Common.6FD769ED          ;  CUR_OBJ_PTR->X <> OBJ_X ==> goto NEXT_OBJ
6FD769E8  |. 394F 10              |CMP DWORD PTR DS:[EDI+10],ECX        ;  CUR_OBJ_PTR->Y = OBJ_Y ?
6FD769EB  |. 74 2B                |JE SHORT D2Common.6FD76A18           ;  CUR_OBJ_PTR->Y = OBJ_Y ==> goto ADD_PATHS


NEXT_OBJ :
==========
6FD769ED  |> 8B7F 1C              |MOV EDI,DWORD PTR DS:[EDI+1C]        ;  EDI = CUR_OBJ_PTR->NEXT
6FD769F0  |. 85FF                 |TEST EDI,EDI                         ;  CUR_OBJ_PTR->NEXT = NULL ?
6FD769F2  |.^75 EF                \JNZ SHORT D2Common.6FD769E3          ;  CUR_OBJ_PTR->NEXT <> NULL ==> goto TRY_THIS_OBJ


OBJ_NOT_FOUND :
===============

It appear that in the case of NPC paths with incorect object X & Y reference, we don't alert the user, we just skip theses incorrect paths datas.

6FD769F4  |> 8B4424 14            MOV EAX,DWORD PTR SS:[ESP+14]         ;  EAX = VERSION
6FD769F8  |. 8D34EE               LEA ESI,DWORD PTR DS:[ESI+EBP*8]      ;  ESI += PATH_NUM * 8 (skip all PATH X and Y)
6FD769FB  |. 83F8 0F              CMP EAX,0F                            ;  VERSION = 15 ?
6FD769FE  |. 7C 03                JL SHORT D2Common.6FD76A03            ;  VERSION < 15 ==> goto NEXT_NPC

                                                                        ;  else here VERSION >= 15

6FD76A00  |. 8D34AE               LEA ESI,DWORD PTR DS:[ESI+EBP*4]      ;  ESI += PATH_NUM * 4 (skip all PATH ACTION)


NEXT_NPC :
==========
6FD76A03  |> 8B4424 24            MOV EAX,DWORD PTR SS:[ESP+24]         ; 
6FD76A07  |. 48                   DEC EAX                               ; 
6FD76A08  |. 894424 24            MOV DWORD PTR SS:[ESP+24],EAX         ;  NPC_NUM --
6FD76A0C  |.^75 BA                JNZ SHORT D2Common.6FD769C8           ;  NPC_NUM <> 0 ==> goto START_NEW_NPC


END_OF_LOAD :
=============
6FD76A0E  |> 5F                   POP EDI                               ;  restore EDI
6FD76A0F  |. 5E                   POP ESI                               ;  restore ESI
6FD76A10  |. 5D                   POP EBP                               ;  restore EBP
6FD76A11  |. 5B                   POP EBX                               ;  restore EBX
6FD76A12  |. 83C4 18              ADD ESP,18                            ;  free local variables except the last one
6FD76A15  |. C2 0400              RETN 4                                ;  free last local variable
                                                                        ;     from SVR : Pascal Calling ???


ADD_PATHS :
===========

We can only be here if CUR_OBJ_PTR is not NULL. But just for safety, we test for it again. If NULL, then we'll skip these paths data, without alerting the user (hey, it's impossible to have the pointer to NULL after all).

6FD76A18  |> 85FF                 TEST EDI,EDI                          ;  CUR_OBJ_PTR = NULL ?
6FD76A1A  |.^74 D8                JE SHORT D2Common.6FD769F4            ;  CUR_OBJ_PTR = NULL ==> goto OBJ_NOT_FOUND

                                                                        ;  else here we have an OBJECT to add PATHS

6FD76A1C  |. 6A 00                PUSH 0                                ;  PUSH 0
6FD76A1E  |. 68 B6050000          PUSH 5B6                              ;  PUSH 1462
6FD76A23  |. 68 EC46DD6F          PUSH D2Common.6FDD46EC                ;  ASCII "C:\Projects\Diablo2\Source\D2Common\DRLG\Preset.cpp"
6FD76A28  |. BA 08000000          MOV EDX,8                             ;  EDX = 8
6FD76A2D  |. 33C9                 XOR ECX,ECX                           ;  ECX = 0
6FD76A2F  |. E8 44CF0300          CALL <JMP.&Fog.#10045>                ;  allocate PATHS_INFO of 1 object

6FD76A34  |. 8D546D 00            LEA EDX,DWORD PTR SS:[EBP+EBP*2]      ;  EDX = PATH_NUM * 3
6FD76A38  |. 33C9                 XOR ECX,ECX                           ;  ECX = 0
6FD76A3A  |. 6A 00                PUSH 0                                ;  PUSH 0
6FD76A3C  |. 68 B7050000          PUSH 5B7                              ;  PUSH 1463
6FD76A41  |. 68 EC46DD6F          PUSH D2Common.6FDD46EC                ;  ASCII "C:\Projects\Diablo2\Source\D2Common\DRLG\Preset.cpp"
6FD76A46  |. 8947 18              MOV DWORD PTR DS:[EDI+18],EAX         ;  CUR_OBJ_PTR->PATH_PTR = EAX
6FD76A49  |. C1E2 02              SHL EDX,2                             ;  EDX = PATH_NUM * sizeof(ACTION) (* 12)
6FD76A4C  |. E8 27CF0300          CALL <JMP.&Fog.#10045>                ;  allocate table of PATH_NUM ACTION struct
6FD76A51  |. 8B4F 18              MOV ECX,DWORD PTR DS:[EDI+18]         ;  ECX = CUR_OBJ_PTR->PATH_PTR
6FD76A54  |. 85ED                 TEST EBP,EBP                          ;  PATH_NUM positive ?
6FD76A56  |. 8941 04              MOV DWORD PTR DS:[ECX+4],EAX          ;  PATH_PTR->ACTION_PTR = EAX
6FD76A59  |. 8B57 18              MOV EDX,DWORD PTR DS:[EDI+18]         ;  EDX = CUR_OBJ_PTR->PATH_PTR
6FD76A5C  |. 892A                 MOV DWORD PTR DS:[EDX],EBP            ;  PATH_PTR->ACTION_NUM = PATH_NUM
6FD76A5E  |.^7E A3                JLE SHORT D2Common.6FD76A03           ;  PATH_NUM <= 0 ==> goto NEXT_NPC

6FD76A60  |. 8B4C24 14            MOV ECX,DWORD PTR SS:[ESP+14]         ;  ECX = VERSION
6FD76A64  |. 33C0                 XOR EAX,EAX                           ;  IDX = 0
6FD76A66  |. 896C24 2C            MOV DWORD PTR SS:[ESP+2C],EBP         ;  TMP = PATH_NUM


LOAD_PATH :
===========

6FD76A6A  |> 8B57 18              /MOV EDX,DWORD PTR DS:[EDI+18]        ;  EDX = CUR_OBJ_PTR->PATH_PTR
6FD76A6D  |. 8B2E                 |MOV EBP,DWORD PTR DS:[ESI]           ;  EBP = PATH_X
6FD76A6F  |. 83C6 04              |ADD ESI,4                            ;  move pointer to next data (PATH_Y)
6FD76A72  |. 8B52 04              |MOV EDX,DWORD PTR DS:[EDX+4]         ;  EDX = PATH_PTR->ACTION_PTR
6FD76A75  |. 83C6 04              |ADD ESI,4                            ;  move pointer to next data (ACTION if VERSION >= 15)
6FD76A78  |. 83F9 0F              |CMP ECX,0F                           ;  VERSION = 15 ?
6FD76A7B  |. 896C02 04            |MOV DWORD PTR DS:[EDX+EAX+4],EBP     ;  ACTION_PTR[IDX]->PATH_X = PATH_X

6FD76A7F  |. 8B57 18              |MOV EDX,DWORD PTR DS:[EDI+18]        ;  EDX = CUR_OBJ_PTR->PATH_PTR
6FD76A82  |. 8B6E FC              |MOV EBP,DWORD PTR DS:[ESI-4]         ;  EBP = PATH_Y
6FD76A85  |. 8B52 04              |MOV EDX,DWORD PTR DS:[EDX+4]         ;  EDX = PATH_PTR->ACTION_PTR
6FD76A88  |. 896C02 08            |MOV DWORD PTR DS:[EDX+EAX+8],EBP     ;  ACTION_PTR[IDX]->PATH_Y = PATH_Y

6FD76A8C  |. 8B57 18              |MOV EDX,DWORD PTR DS:[EDI+18]        ;  EDX = CUR_OBJ_PTR->PATH_PTR
6FD76A8F  |. 8B52 04              |MOV EDX,DWORD PTR DS:[EDX+4]         ;  EDX = PATH_PTR->ACTION_PTR
6FD76A92  |. 7C 0A                |JL SHORT D2Common.6FD76A9E           ;  VERSION < 15 ==> goto DEFAULT_ACTION

                                                                        ;  else here VERSION >= 15

6FD76A94  |. 8B2E                 |MOV EBP,DWORD PTR DS:[ESI]           ;  EBP = ACTION
6FD76A96  |. 83C6 04              |ADD ESI,4                            ;  move pointer to next data
6FD76A99  |. 892C02               |MOV DWORD PTR DS:[EDX+EAX],EBP       ;  ACTION_PTR[IDX]->ACTION = ACTION
6FD76A9C  |. EB 07                |JMP SHORT D2Common.6FD76AA5          ;  goto ACTION_OK


DEFAULT_ACTION :
================
6FD76A9E  |> C70402 01000000      |MOV DWORD PTR DS:[EDX+EAX],1         ;  ACTION_PTR[IDX]->ACTION = 1


ACTION_OK :
===========
6FD76AA5  |> 8B5424 2C            |MOV EDX,DWORD PTR SS:[ESP+2C]        ; 
6FD76AA9  |. 83C0 0C              |ADD EAX,0C                           ;  IDX++
6FD76AAC  |. 4A                   |DEC EDX                              ; 
6FD76AAD  |. 895424 2C            |MOV DWORD PTR SS:[ESP+2C],EDX        ;  TMP--
6FD76AB1  |.^75 B7                \JNZ SHORT D2Common.6FD76A6A          ;  TMP <> 0 ==> goto LOAD_PATH
6FD76AB3  \.^E9 4BFFFFFF          JMP D2Common.6FD76A03                 ;  goto NEXT_NPC


_________________
DT1 Tools - DS1 Editor - MPQ list file - Extracting D2 Animation tutorial
"Sorry I can't give you offsets or anything, my dlls are always very mutant compared to what's in the release" - Isolde, aka Peter Hu, 30 Jun 2002


Top
 Profile E-mail  
 
PostPosted: Sun Nov 24, 2002 7:54 am 
 Post subject:
 
Offline
Moderator
Moderator
Principality
User avatar

Age: 35
Joined: Sat May 25, 2002 2:39 pm
Posts: 2738
Location: La Garenne Colombes (near Paris)
Gender: Male
I must have been blind when I found the unknown layer & the unknown data between the objects & the npc paths. I just found what they're used for. The 2nd datas are X & Y position of groups in the Group Layer, and it have their Width & Height too.

Let's take an exemple : Data\Global\Tiles\Expansion\Siege\5x1barricade_brk_rules.ds1

Layer GROUPS TAGS
=================

   \ X|
  Y \ |    0         1       2         3       4        5
  --- + -------- -------- -------- -------- -------- --------
   0 | 00000001 00000000 00000000 00000000 00000000 00000000
   1 | 00000001 00000000 00000000 00000000 00000000 00000000
   2 | 00000001 00000000 00000000 00000000 00000000 00000000
   3 | 00000001 00000000 00000000 00000000 00000000 00000000
   4 | 00000001 00000000 00000000 00000000 00000000 00000000
   5 | 00000000 00000000 00000000 00000000 00000000 00000000
   6 | 00000004 00000000 00000000 00000000 00000000 00000000
   7 | 00000004 00000000 00000000 00000000 00000000 00000000
   8 | 00000004 00000000 00000000 00000000 00000000 00000000
   9 | 00000004 00000000 00000000 00000000 00000000 00000000
  10 | 00000004 00000000 00000000 00000000 00000000 00000000
  11 | 00000000 00000000 00000000 00000000 00000000 00000000
  12 | 0000000A 00000000 00000000 00000000 00000000 00000000
  13 | 0000000A 00000000 00000000 00000000 00000000 00000000
  14 | 0000000A 00000000 00000000 00000000 00000000 00000000
  15 | 0000000A 00000000 00000000 00000000 00000000 00000000
  16 | 0000000A 00000000 00000000 00000000 00000000 00000000
  17 | 00000000 00000000 00000000 00000000 00000000 00000000
  18 | 00000013 00000000 00000000 00000000 00000000 00000000
  19 | 00000013 00000000 00000000 00000000 00000000 00000000
  20 | 00000013 00000000 00000000 00000000 00000000 00000000
  21 | 00000013 00000000 00000000 00000000 00000000 00000000
  22 | 00000013 00000000 00000000 00000000 00000000 00000000
  23 | 00000000 00000000 00000000 00000000 00000000 00000000
  24 | 0000001F 0000001F 0000001F 0000001F 0000001F 00000000
  25 | 00000000 00000000 00000000 00000000 00000000 00000000
  26 | 00000028 00000028 00000028 00000028 00000028 00000000
  27 | 00000000 00000000 00000000 00000000 00000000 00000000
  28 | 0000002D 0000002D 0000002D 0000002D 0000002D 00000000
  29 | 00000000 00000000 00000000 00000000 00000000 00000000
  30 | 00000032 00000032 00000032 00000032 00000032 00000000


GROUPS DEFINITION : 8 groups

    Num   Tile X   Tile Y    Width   Height         ?
   ---- -------- -------- -------- --------  --------
      1        0       30        5        1        14
      2        0       28        5        1        14
      3        0       26        5        1        14
      4        0       24        5        1        14
      5        0       18        1        5        14
      6        0       12        1        5        14
      7        0        6        1        5        14
      8        0        0        1        5        14

Now, for each groups define in the precedent data, we read the corresponding tags :

    Num  Tag
   ---- ----
      1  032
      2  02D
      3  028
      4  01F
      5  013
      6  00A
      7  004
      8  001


There are 2 ways to understand the relations between the layer and the definitions.

Imagine that the user is in my ds1 editor, where it see each tiles. When moving the mouse over the tiles of that map, the program know immediatly (by checking the Tag at that Tile position) if that tile is part of a Group (if tag = 0 then not part of a group). If the Tile is part of a group, the Tag in itself is useless, because we'll check all the Groups Definition structure and compare the Tile position with the area of the groups in there. The mouse is on the Tile 1, 24. The Tag is 1F, so we're on a group. Which one ? By checking the Definition structure, we'll find that this tile fit in the area # 4 : (0, 24) ---> (4, 24). And we find another data then : the last column which is always set to 14 in that ds1, but can be another values in other ds1.

The other way to use it is by taking an area. We can then check the GROUPS layer and deduce its Tag value (problem : by this method several tags can be found for 1 area).

Now, what all these datas are used for ? Two solutions :
  • either they have some meaning in the Level Editor of Blizzard, to help to select a group for instance, but are not used by the game anymore (we already have such useless datas : the file strings in the header, where some old ds1 use files with .TG1 and not .DT1 extension).
  • Or the other solution is that these datas are still used by the game, and therefore for what ? I think of some miscelaneous gfx that appear randomly, like Trees, corpse. I have the intuition that theses datas are useless... but I need to made some tests for that.



Btw, corected an error : the Type 1 lookup table is not ACT * 75 dwords, but ACT * 60.

_________________
DT1 Tools - DS1 Editor - MPQ list file - Extracting D2 Animation tutorial
"Sorry I can't give you offsets or anything, my dlls are always very mutant compared to what's in the release" - Isolde, aka Peter Hu, 30 Jun 2002


Top
 Profile E-mail  
 
PostPosted: Sun Nov 24, 2002 3:07 pm 
 Post subject:
 
Offline
Champion of the Light

Joined: Sun Jun 02, 2002 2:08 am
Posts: 263
Gender: None specified
Whoa, excellent post! Although it's not surprising that a post like this about ds1 files comes from you ;)


Top
 Profile  
 
PostPosted: Sun Nov 24, 2002 6:37 pm 
 Post subject:
 
Offline
Senior Admin
Senior Admin
Cherub
User avatar

Age: 54
Joined: Sat May 25, 2002 7:28 am
Posts: 12058
Location: Percussion U
Gender: Male
Excellent work, Paul! There is so much information here, it will probably be next year before I understand it all. I am sure the next version of your editor will be a formidable tool, even in comparison with your current version!

_________________
Do the right thing. It will gratify some people and astonish the rest.
~ Mark Twain
Run Diablo II in any version for mods: tutorial
The Terms of Service!! Know them, abide by them, and enjoy the forums at peace.
The Beginner's Guide v1.4: (MS Word | PDF) || Mod Running Scripts || TFW: Awakening


Top
 Profile  
 
PostPosted: Sun Nov 24, 2002 6:42 pm 
 Post subject:
 
Offline
Moderator
Moderator
Principality
User avatar

Age: 35
Joined: Sat May 25, 2002 2:39 pm
Posts: 2738
Location: La Garenne Colombes (near Paris)
Gender: Male
He he thanks ;) . What surprised me is that, despite it was the first time I try to decode an asm listing, it was not really that difficult in fact. But I'm glad that SVR was with me on that deciphering, it really need both of us to achieve this result, after near 2 weeks of hard works.

Now that I feel a lot more confident with asm, I'll work again on something else later, who know ? But I have discovered also that's it's such a time-consumed process :oops: Hence, my congratulations goes to all our code-editing programmers here, they're great !

Edit : Btw, next year is only in 1 month ;)

_________________
DT1 Tools - DS1 Editor - MPQ list file - Extracting D2 Animation tutorial
"Sorry I can't give you offsets or anything, my dlls are always very mutant compared to what's in the release" - Isolde, aka Peter Hu, 30 Jun 2002


Top
 Profile E-mail  
 
PostPosted: Mon Nov 25, 2002 7:03 am 
 Post subject:
 
Offline
Moderator
Moderator
Principality
User avatar

Age: 35
Joined: Sat May 25, 2002 2:39 pm
Posts: 2738
Location: La Garenne Colombes (near Paris)
Gender: Male
For a better understanding of the ds1 format, here's a simple DS1 format revision history, before I make a more serious Doc.

In Version 1, here's the format :

  • VERSION
  • WIDTH
  • HEIGHT
  • 1 WALL layer
  • 1 FLOOR layer
  • 1 ORIENTATION layer for the WALL layer
  • 1 reserved layer (not used)
  • 1 SHADOW layer

version 2 introduced OBJECTS
version 3 introduced FILENAMES
version 4 introduced WALL_NUM, and changed the order of layers
version 5 made some changes to the objects ID & TYPE
version 6 introduced a FLAG data to each OBJECTS
version 8 introduced ACT, and change the ORIENTATION meaning (older ds1 need convertions)
version 9 introduced a jump of 2 dwords right after the FILENAMES
version 10 introduced TAG_TYPE (but not used until version 12 ?)
version 12 use the reserved layer, it become the TAG layer
version 13 introduced an unknown dword to each GROUP
version 14 canceled the jump of 2 dwords right after the FILENAMES, and introduced NPC_PATH
version 15 introduced the ACTION data to each NPC_PATH
version 16 introduced FLOOR_NUM
version 18 introduced a jump of 1 dword at the begening of the GROUP

Now (Version 18), the format is :

  • VERSION
  • WIDTH
  • HEIGHT
  • ACT
  • TAG_TYPE
  • FILENAMES
  • WALL_NUM
  • FLOOR_NUM
  • WALL_NUM (WALL + ORIENTATION) layers
  • FLOOR_NUM layers of FLOOR
  • 1 SHADOW layer
  • optional TAG layer (only if TAG_TYPE is 1 or 2)
  • OBJECTS
  • optional GROUPS (only if TAG_TYPE is 1 or 2)
  • NPC_PATH

Or "why my editor (and the Isilweo's one too) had problems for loading some ds1" ;)

_________________
DT1 Tools - DS1 Editor - MPQ list file - Extracting D2 Animation tutorial
"Sorry I can't give you offsets or anything, my dlls are always very mutant compared to what's in the release" - Isolde, aka Peter Hu, 30 Jun 2002


Top
 Profile E-mail  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 10 posts ] 


Who is online

Users browsing this forum: No registered users and 0 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
Black Rock template by onyx (based on BlackSoul for phpBB2)
 

Powered by MKPortal ©2003-2008 mkportal.it